useContext
-react context의 필요성
부모=> 자식 컴포넌트로 데이터 전달할 때 props로 전달했어.
부모 => 자식 => 그 자식 => 그자식의 자식 => prop driling
이런 위에서 아래로 props를 보내는 props drilling
=> 깊이가 너무 깊어지면 부모에서 자식으로 넘겨줄 때 여러개의 컴포넌트있을 경우
어디에서 prop이 왔는 지 알수 없기도하고 오류가 무조건 생기며 원인 파악 힘들어
하지만 context API를 쓰면
전역으로 데이터를 관리할 수 있어
어떤 컴포넌트든 전역적으로 선언되어있는 데이터에 접근 가능해.
contextAPI 필수 개념
- createContext : context 생성 (컨텍스트를 만드는)
- Consumer : context 변화 감지 (컨텍스트의 변화를 감지하는 컨슈머)
- Provider : context 전달(to 하위 컴포넌트) (컨텍스트를 하위 컨텍스트로 전달할 수 있는)
예시1. GF => Child한테 어떤 정보를 알려줘서 Child가 그 내용을 출력하도록.
-App.jsx
import React from "react";
function App() {
return <GrandFather />
}
export default App;
-Child.jsx
import React from "react";
function Child({houseName, pocketMoney}) {
console.log(houseName)
console.log(pocketMoney)
return <div>
나는 이 집안의 막내에요!
<br />
할아버지가 우리 집 이름은 <span>{houseName}</span>라고 하셨어요.
<br />
게다가 용돈도 <span>{pocketMoney}</span>원 만큼이나 주셨어요!
</div>
}
export default Child;
- 결과
Child컴포넌트
import React from "react";
function Child({houseName, pocketMoney}) {
console.log(houseName)
console.log(pocketMoney)
const style={
color = "red",
fontWeight: "900"
}
return <div>
나는 이 집안의 막내에요!
<br />
할아버지가 우리 집 이름은 <span style={style}>{houseName}</span>라고 하셨어요.
<br />
게다가 용돈도 <span style={style}>{pocketMoney}</span>원 만큼이나 주셨어요!
</div>
}
export default Child;
-Father.jsx
import React from "react";
function Father({houseName, pocketMoney}) {
return <Child houseName={houseName} pocketMoney={pocketMoney} />
}
export default Father;
-GrandFather.jsx
import React from "react";
function GrandFather() {
const houseName = "라이트하우스";
const pocketMoney = 10000; // 손자한테 전달
return <Father houseName={houseName} pocketMoney={pocketMoney} />
}
export default GrandFather;
- 이 단계가 100개라면 엄청 비효율 적이야. 그래서 useContext hook을 사용하는거야.
useContext
- 사용법
import { createContext } from "react";
// provider로 주입하는 하위 컴포넌트에 들어가서 사용할 수 있는
// 컨텍스트가 생성이 된거야 이걸 가져다가 쓸거야.
export const FamilyContext = createContext(null);
- 용돈을 지급받는 곳이 할아버지 GF 컴포넌트
- 그래서 GF에서 쓸 거야.
그래서 그냥 Father 컴포넌트에 보내주는 게 아니라 context를 불러와서 감싸줄거야.
그리고 Father에서 보내주는 props는 필요없어.
이제 props로 보내주는 게 아니라
어차피 FamilyContext 만든 걸 통해서 외부로 접근해서 보내줄거야.
그리고 provider를 적용해줄거야. 쩜으로 접근해서 제공하는 자인 provider을 적용할 거야.
-GrandFather.jsx
import React from "react";
function GrandFather() {
const houseName = "라이트하우스";
const pocketMoney = 10000; // 손자한테 전달
return (
<FamilyContext.Provider
value={{houseName, pocketMoney}}
> //context를 provider할 때 보내는 객체
<Father />
</FamilyContext.Provider>
}
}
export default GrandFather;
속성(프로퍼티)로 value={}해서 보내는 객체는
{
houseName: houseName,
pocketMoney: pocketMoney
}
그리고 javascript에선 키 밸류가 같으면 단축 명명을 할 수 있어서
{ houseName, pocketMoney}로 쓸 수 잇는 거야
그러면 이제 Father 컴포넌트도 프롭스를 받을 필요 엄성
-Father.jsx
import React from "react";
function Father() {
return <Child />
}
export default Father;
이제 Child컴포넌트도 props를 안 받고 props에 의존하지 않고 context를 의존해야해.
그래서 context로 부터 데이터를 받아올 거야.
import React,{ useContext} from "react";
const style={
color = "red",
fontWeight: "900"
}
function Child({houseName, pocketMoney}) {
const data = useContext(FamilyContext);
console.log("data", data); // {houseName: "라이트하우스", pocketMoney : 10000}
const { houseName, pocketMoney} = data;
return <div>
나는 이 집안의 막내에요!
<br />
할아버지가 우리 집 이름은 <span style={style}>{data.houseName}</span>라고 하셨어요.
<br />
게다가 용돈도 <span style={style}>{data.pocketMoney}</span>원 만큼이나 주셨어요!
</div>
}
export default Child;
-렌더링 문제
useContext를 사용할 때, Provider에서 제공한 value가 달라지면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 돼. 그래서 value부분을 항상 신경써줘야 해.
Provider의 value가 달라질 때마다 모든 컴포넌트가 리렌더링 돼.
그 해결책이 "메모이제이션"이야.
원래는 이렇게 props로 단계별로 전달받아서 썼지만
이제 FamilyContext로 어느 컴포넌트로 접근할 수 있게 끔한거야.
*참고 사이트
- https://ko.react.dev/learn/passing-data-deeply-with-context
느낀점
- props만 쓰면 페이지나 기능이 많아지게 되면 props drilling이 심해져서 정말 관리하기 힘들 것 같아. 대신 Context도 provider로 보내는 value가 필요하면 처음으로 찾아가서 설정을 해주고 데이터를 불러서 써야하고 필요한 value값과 페이지가 많아지면 props도 같이 계속 써야하는 건 같은 것 같아. 그래도 props만 전달할 때보단 비교적 편하겠지만..
'개발일지' 카테고리의 다른 글
[TIL] 24_0129 useDispatch의 역할 (2) | 2024.01.29 |
---|---|
[TIL] 24_0128 리덕스 세팅하면서 useSelector로 state확인하며 경고발생 (0) | 2024.01.28 |
[TIL] 24_0126 리액트에서의 map사용, key prop 오류 (0) | 2024.01.26 |
[TIL] 두 번째 개인 프로젝트 피드백 반영, 베이직 과제 후 (0) | 2024.01.25 |
[TIL] 24_0124 useEffect, useRef (0) | 2024.01.24 |