리액트에서 제공하는 props 없이 state 공유하는 문법
Detail 페이지의 상세정보 tab에 상품의 재고를 기록해볼 것이다
우선 App 컴포넌트에 stock state를 만들어 놓는다
(임시 데이터)
function App() {
let [stock,setStock]=useState([10,11,12])
이제 이 state를 공유하기 위한 세팅이 두가지 필요하다
App.js 에 글로벌 변수로 만든다
// state 보관함
export let Context= createContext()
stock state를 Detail 페이지에서 사용할 것이기 때문에
Context.Provider
을 통해 Detail 컴포넌트를 감싸준다
그리고 value 속성을 통해 stock을 저장한다
<Route path='/detail/:id' element={
<Context.Provider value={{stock}}>
<Detail data={data} />
</Context.Provider>
}></Route>
이제 Context로 감싼 모든 컴포넌트와 그 자식 컴포넌트는 state를 props 전송 없이 사용 가능해진다
이제 Detail.js에서 사용만 하면 된다
App.js에서 만든 context를 import 해온다
import {Context} from './../App.js'
function TabContent({tab,data}){
let {stock}= useContext(Context)
let [addClass,setAddClass]= useState(false)
//tab 상태가 변할 때마다 코드를 실행시키기 위해 useEffect 사용
useEffect(()=>{
setTimeout(() => setAddClass(true), 500);
return () => setAddClass(false);
},[tab])
return (
<div className={`start ${addClass ? 'end': ''}`}>
{[<div>{data[0].title}의 상세정보입니다<p>재고:{stock[0]}</p></div>,<div>구매 후기입니다</div>,<div>질문 게시판입니다</div>][tab]}
</div>
)
}
useContext로 만들어둔 context를 불러오면 그 자리에 공유했던 state가 전부 남는다
그래서 distructuring 문법을 통해 내가 필요한 stock 이라는 state를 불러왔다
그리고 원하는 곳에서 사용하면 끝 !!
이렇게 자손컴포넌트인 TabContent 에서까지 사용이 잘 되는 걸 확인할 수 있다
context API 는 잘 사용하지 않는 문법이다
- state 변경시 해당 state를 사용하지 않는 컴포넌트까지 전부 불필요하게 재렌더링이 되고
- useContext() 를 쓰고 있는 컴포넌트는 나중에 다른 파일에서 재사용할 때 Context를 import 하는게 귀찮다
유익한 글이었습니다.