리액트

[리액트] 자식이 부모의 state 가져다쓰고 싶을 때는 props

front-hyun 2023. 8. 30. 14:52

모든 변수는 함수탈출불가능하다. 

글제목이 정의되지 않았다는 오류메시지가 뜨는데.. 그 이유는 다른 component에서 정의했기 때문이야. 이것을 props문법 사용해서 해결 가능해 !!!

자식 컴포넌트가 부모 컴포넌트에 있던 state를 쓰고 싶으면

그냥 쓰면 안되고 props로 전송해서 써야합니다. 

뭔소린지 알아봅시다. 

일단 모달창 잘 띄우고 시작해봅시다. 

 

 

 

 

<Modal>안에 글제목 state 가 필요한데

 

저번에 만든 <Modal> 내부에 글제목 state를 집어넣고 싶으면 어떻게하죠? 

예를 들면 이렇게 하면 될듯요 

 

 

function App (){
  let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
  return (
    <div>
      <Modal></Modal>
    </div>
  )
}

function Modal(){
  return (
    <div className="modal">
      <h4>{ 글제목[0] }</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

▲ 하지만 제대로 실행되지 않습니다.

'글제목'이라는 변수가 define 되지 않았다고 에러가 뜹니다.

왜냐면 글제목이라는 state 변수는 function App()에 있지 function Modal()에 없으니까요.

자바스크립트에선 다른 함수에 있는 변수를 마음대로 가져다쓸 수 없습니다. 

 

 

 

 

 

App.js 파일 내에 Modal 컴포넌트를 정의했으니깐 App이 Modal을 품고있어. 그러니깐 부모와 자식이라고 할 수 있지?

 

근데 컴포넌트 2개가 부모/자식 관계인 경우엔 가능합니다. 

(다른 컴포넌트 안에 있는 컴포넌트를 자식컴포넌트라고 부릅니다)

 

 

 

props라는 문법을 사용해서 자식이 부모가 가지고 있던 state 사용가능해!

 

부모 컴포넌트의 state를 자식 컴포넌트로 전송해줄 수 있습니다. 그럼 자식도 사용가능

전송시엔 props라는 문법을 사용합니다. 

 

그니깐 부모 파일에 자식 컴포넌트를 정의했어. 결론적으로 자식 컴포넌트는 부모 컴포넌트의 state를 사용할 수 없어. 근데 쓰고 싶다면? props를 사용하라고. 

 

부모 컴포넌트에 있는 글제목 state를 props로 전달해주면 Modal 컴포넌트에서 사용이 가능하다. 

 

 

 

props로 부모 -> 자식 state 전송하는 법 

 

2개의 step을 따라주시면 됩니다.

1. 자식컴포넌트 사용하는 곳에 가서 <자식컴포넌트 작명={state이름} /> 

내가 원하는 props명 = {자식컴포넌트에서 사용하고 싶은 부모 state}

2. 자식컴포넌트 만드는 function으로 가서 props라는 파라미터 등록 후 props.작명 사용

props.(내가 원하는 props명)

하지만 이론만 설명하면 이해가 되지 않으니 예시를 보아야합니다.

 

 

 

글제목이라는 부모 컴포넌트의 state를 자식 컴포넌트 <Modal>에 전송해봅시다.

function App (){
  let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
  return (
    <div>
      <Modal 글제목={글제목}></Modal> //(1) App 컴포넌트가 Modal 컴포넌트를 사용하므로 여기서 작명
    </div>
  )
}

function Modal(props){ //(2) 자식 Modal 컴포넌트에서 Props 전달받아서 사용하면 됨 
  return (
    <div className="modal">
      <h4>{ props.글제목[0] }</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

1. 자식컴포넌트 사용하는 곳에 가서 <자식컴포넌트 작명={state이름} /> 

2. 자식컴포넌트 만드는 곳에 가서 props라는 파라미터 등록 후 props.작명 사용하면 됩니다.

props 전송문법은 중요하니 외워두도록 합시다. 

 

 

 

(참고1) props는 <Modal 이런거={이런거}  저런거={저런거}> 이렇게 10개 100개 1000개 무한히 전송이 가능합니다.

여러 개의 props 생성 가능 !!

(참고2) 꼭 state만 전송할 수 있는건 아닙니다. 

<Modal 글제목={변수명}> 일반 변수, 함수 전송도 가능하고 

<Modal 글제목="강남우동맛집"> 일반 문자전송은 중괄호 없이 이렇게 해도 됩니다.

 

 

 

 

▲ 자식 → 부모 패륜방향 전송은 불가능합니다.

 

 

 

▲ 옆집 컴포넌트로의 불륜전송도 불가능합니다. 

 

 

 

 

 

 

props는 함수 파라미터 문법이랑 똑같습니다

 

함수에 파라미터같은거 왜 넣죠?

자바스크립트 기초강의에서는 

"함수 하나로 다양한 기능을 사용하기 위해서 쓰는게 파라미터 문법" 이랬습니다.

props도 실은 파라미터랑 똑같은 문법입니다. 

그래서 이런 식으로 응용도 가능한데 

 

 

function Modal(props){
  return (
    <div className="modal" style={{ background : 'skyblue' }}>
      <h4>{ props.글제목[0] }</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

갑자기 하늘색 배경의 모달창이 필요하면 저렇게 스타일 넣으면 됩니다. 

근데 이번엔 오렌지색 모달창이 필요하면 어떻게합니까? 

갑자기 노란색 모달창도 필요하면요?

 

가장 쉬운 방법은

function Modal2() {}

function Modal3() {}

....

이렇게 컴포넌트를 또 만들어서 각각 배경색을 다르게 만들어도 되겠지만 

내용이 똑같은데 배경색만 다르면 굳이 같은 함수 여러개 만들 필요가 없습니다. 

 

 

 

function Modal(props){
  return (
    <div className="modal" style={{ background : props.color }}>
      <h4>{ props.글제목[0] }</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

props.color 이런 식으로 구멍을 뚫어놓으면 이제 컴포넌트 사용할 때

<Modal color={'skyblue'} /> 이러면 하늘색 모달창이 생성됩니다. 

<Modal color={'orange'} /> 이러면 오렌지색 모달창이 생성됩니다.

그래서 비슷한 컴포넌트를 또 만들 필요가 없어지는 것입니다. 

 

 

그래서 내가 함수 파라미터 문법을 잘 알고 있다면

그런 식으로도 응용가능합니다. 

그래서 결론은 자바스크립트 잘해야 리액트를 잘합니다. 

 

오늘의 숙제 : 

모달창안에 글수정버튼 만들고

그거 누르면 첫 글제목이 '여자코트 추천'으로 바뀌는 기능을 만들어봅시다.

 

나의 풀이

import './App.css';
import { useState } from 'react';

function App() {
  let [글제목, 글제목변경]=useState(['남자 코트 추천','강남 우동맛집','파이썬 독학']);
  let[likes,setLikes]=useState([0,0,0]);
  let [modal, setModal]=useState(false);
  return (
    <div className="App">
     <div className="black-nav">
      <h4>ReactBlog</h4>
     </div>

     {
      글제목.map(function(a, i){
        return(
          <div className="list" key={i}>
      <h4 onClick={()=>{setModal(true);}}>{글제목[i]} <span onClick={()=>{setLikes(likes[i]+1);}}>❤</span> { likes[i]}</h4>
      <p>2월 17일 발행</p>
     </div>
        )
      })
     }
     {
      (modal == true) ? <Modal title={글제목} change={()=>{
        let copy=[...글제목];
        copy[0]='여자 코트 추천'
        글제목변경(copy)
      }}/>:null
     }
   
   
    </div>
  );
}

function Modal(props){
  return(
    <div className="modal">

<h4>{props.title[0]}</h4>
    <p>날짜</p>
    <p>상세내용</p>
    <button onClick={props.change} >글수정</button>
   </div>
 
  )
}


export default App;

강의 풀이

import './App.css';
import { useState } from 'react';

function App() {
  let [글제목, 글제목변경]=useState(['남자 코트 추천','강남 우동맛집','파이썬 독학']);
  let[likes,setLikes]=useState([0,0,0]);
  let [modal, setModal]=useState(false);
  return (
    <div className="App">
     <div className="black-nav">
      <h4>ReactBlog</h4>
     </div>

     {
      글제목.map(function(a, i){
        return(
          <div className="list" key={i}>
      <h4 onClick={()=>{setModal(true);}}>{글제목[i]} <span onClick={()=>{setLikes(likes[i]+1);}}>❤</span> { likes[i]}</h4>
      <p>2월 17일 발행</p>
     </div>
        )
      })
     }
     {
      (modal == true) ? <Modal title={글제목} 글제목변경={글제목변경}/>:null
     }
   
   
    </div>
  );
}

function Modal(props){
  return(
    <div className="modal">

<h4>{props.title[0]}</h4>
    <p>날짜</p>
    <p>상세내용</p>
    <button onClick={()=>{props.글제목변경(['여자코트추천', '강남 우동맛집','파이썬 독학'])}} >글수정</button>
   </div>
 
  )
}


export default App;