2차 프로젝트를 하는 도중에, props 전달을 부모에서 자식으로, 자식에서 부모로, 부모에서 다른 자식으로 전달해야하는 경우를 만났다.
이 흐름(flow)을 한번에 이해하는게 어려워서 프로젝트 도중이지만, 기록을 해본다.
내가 구현하고 싶었던 기능은, 왼쪽 상단의 아이콘을 클릭했을 때, filter navbar가 나오는 것처럼, 오른쪽의 Filter를 클릭했을 때도 filter navbar가 나오는 기능을 구현하고 싶었다.
// 코드가 너무 길어서 필요한 부분만 가져왔는데 그래도 길구나.
// ProductList(부모 컴포넌트)
import React, { useState, useEffect, letsGoJae } from "react";
import Header from "../../Components/Header/Header";
import Title from "./component/Title/Title";
function ProductList() {
const [data, setData] = useState([]);
const [openFilter, setOpenFilter] = useState(false);
useEffect(() => {
fetch("http://localhost:3000/Data/ProductData.json")
.then(response => response.json())
.then(res => {
setData(res.product);
setFilter(res.product[0].sub);
});
}, []);
const [filter, setFilter] = useState([]);
useEffect(() => {
}, [filter]);
const toggleFilter = e => {
setOpenFilter(e);
};
return (
<>
<Header openFilter={openFilter} />
<ProductListPage>
{data
.filter(el => el.category)
.map((el, index) => (
<Title
toggleFilter={e => toggleFilter(e)}
key={index}
productCategory={el.category}
/>
))}
</ProductListPage>
</>
);
}
export default ProductList;
1.openFilter
라는 state를 선언해주고, 초기값으로 false
담아주었다.
2.ProductList(부모 컴포넌트)에서 A 자식 컴포넌트(Title)에 toggleFilter
라는 함수를 전달해주었다.
// A 자식 컴포넌트(Title)
import React, { useState } from "react";
import { MdFilterCenterFocus } from "react-icons/md";
function Title(props) {
const [isFilter, setIsFilter] = useState(false);
return (
<HeaderContainer>
<HeaderRight
onClick={() => {
setIsFilter(!isFilter);
props.toggleFilter(isFilter);
}}
>
<MdFilterCenterFocus size="17" />
Filters
</HeaderRight>
</SangJunPororo>
</HeaderContainer>
);
}
export default Title;
3.부모 컴포넌트에서 선언한 toggleFilter
는 A 자식 컴포넌트(Title)에서 onClick
이벤트가 일어날 때, 실행이 되고, true
값을 부모 컴포넌트로 전달해준다.
<Header openFilter={openFilter} />
4.부모 컴포넌트에서 openFilter
라는 state가 true
가 되고, 이 boolean
값을 B 자식 컴포넌트(Header)에 전달해준다.
// B 자식 컴포넌트(Header)
import React, { useState, useEffect } from "react";
import Filter from "../Filter/Filter";
import { BellRing } from "@styled-icons/boxicons-solid/BellRing";
export default function Header(props) {
const [isFilter, setIsFilter] = useState(true);
useEffect(() => {
setIsFilter(!isFilter);
console.log(isFilter);
}, [props.openFilter]);
return (
<Main>
<HeaderContainer>
<IconBox
onClick={() => {
setIsFilter(!isFilter);
}}
>
<BellRing size="18" color="white" />
</IconBox>
</HeaderContainer>
{isFilter && <Filter />}
</Main>
);
}
5.B 자식 컴포넌트(Header)에서 props
를 받은 후에, useEffect
를 사용해서 props.openFilter
가 변화가 있을 때마다, 즉, A 자식 컴포넌트(Title)에서 onClick 이벤트가 발생할 때마다, isFilter
를 !isFilter
로 바꾼다는 말이다. 즉, toggle
이 일어난다는 말.