공식문서 : https://ko.reactjs.org/docs/lifting-state-up.html
1차 프로젝트를 진행하면서 동일한 데이터에 대한 변경사항을 여러 컴포넌트에 반영해야 하는 순간이 찾아왔다..나의 상황...공식문서 ctrl+c, ctrl+v...
바로 부모 컴포넌트에서 자식 컴포넌트의 데이터 갯수를 보여주는 것이였다. 이를테면 My Heart페이지로 이동하여 각 카테고리를 살펴보면 내가 하트 아이콘을 눌러놓은 제품 또는 Feed의 갯수를 보여주고 카테고리를 클릭시에 제품,Feed를 보여주는 것이였다.
하지만 아무리 공식문서를 들여다봐도 처음엔 이해가 가지 않았다.
이후 내가 짠 코드에서 state를 끌어올리는 간단한 상황을 해결하고 난 후
공식문서와 내가 짠 코드를 기반으로 자식 컴포넌트의 상태를 부모 컴포넌트에 반영하여 변경해주는 상황을 설명해보려고 한다.
우선 공식 문서에서는 두 input 의 변경된 값을 동기화 하는 상황으로 설명하고있다.
섭씨 온도를 적는 input 과 이에 따라 바뀌는 화씨 온도를 적는 input. 즉 두 input 창은 숫자를 입력할 수 있지만 두 input의 데이터는 서로의 영향을 받는다.
섭씨 온도를 적으면 화씨 온도로 변경되어 보여지고, 화씨 온도를 적으면 섭씨 온도로 변경되어 보여진다.
이를 렌더링하는 Calculator컴포넌트가 두 input의 state를 전달해주고, 두 input은 props로 값을 내려받아 항상 동기화된 상태를 유지할 수 있게 된다.
코드는 공식문서를 참조해주세요. https://ko.reactjs.org/docs/lifting-state-up.html
이제 나의 상황을 살펴보면...
//부모 컴포넌트-My Heart페이지
class MyHeart extends React.Component {
state = {
favList: [],
count: "",
};
getLength = (num) => {
// console.log("num >>>> ", num); // 잘 받아오는지 확인!
this.setState({
count: num,
});
}; //함수를 자식 컴포넌트에 넘겨주고 인자를 받아옴.
//원래 전역 변수로 각 컴포넌트들을 객체화하여 호출했으나, 함수를 자식 컴포넌트에 넘겨주어야 하기 때문에 다시 함수를 만들어서 switch문을 사용해 각 컴포넌트를 호출하고 함수를 넘겨주었다.
componentHandler = (id) => {
switch (id) {
case 0:
return <FavListProduct />;
case 1:
return <FavListBrand />;
case 2:
return (
<FavListTwoNineTV
favList={this.state.favList}
getLength={(num) => this.getLength(num)}
/>
); // 우선은 29TV에서 좋아요를 누른 피드의 데이터만 가지고있었기 때문에 이것 먼저 실행.
case 3:
return <FavListPost />;
default:
return <FavListProduct />;
}
};
render() {
console.log("count >>> ", this.state.count); //this.state로 잘 넘어갔는지 확인.
return (
<ul className="myheartCategory">
//<다른 카테고리 lit생략>
<li
onClick={() => this.handleClicked(2)}
className={this.state.activeId === 2 && "myheartCategoryClicked"} //카테고리 클릭시 2를 인자로 넘겨주고 case 2 : 29TV에 해당하는 컴포넌트 호출
>
TV({this.state.count}) //count가 잘 넘어왔다면 보여지게된다.!
</li>
</ul>
)}
}
//자식 컴포넌트
class FavListTwoNineTV extends React.Component {
state = {
favList: [],
};
componentDidMount() {
fetch("http://10.58.1.34:8000/media/mypage/post", {
method: "POST",
body: JSON.stringify({
user: 1,
}),
})
.then((res) => res.json())
.then((res) =>
this.setState(
{
favList: res.my_heart_list,
},
() => this.props.getLength(this.state.favList.length)//리스트를 바로 getLength함수의 인자로 담아서 보내준다. **자식 데이터를 부모한테 넘겨주는 부분..!
)
);
}
그 결과.. 갯수는 넘겨줄 수 있었지만 클릭했을 때 갯수가 보이는 현상이 벌어졌다
때문에 componentDidMount를 부모 컴포넌트로 다시 이동시켜주었고..자식 컴포넌트의 데이터를 올려주는 것이 아닌 부모 컴포넌트에서 내려주는 것으로 변경...^^
하지만 생각 회로를 잘못 설정한 덕분에..자식 컴포넌트에서 부모 컴포넌트로 데이터를 넘겨주는 로직에 대해서 이해할 수 있었다.
실패는 성공의 어머니..^^