✔ 데이터를 넘길 때 props를 사용하지 않는 새로운 방식
아래는 기존에 데이터를 props로 전달하는 방식과 Context로 전달하는 방식을 표현한 예시이다.
Context는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법이다. 그러한 데이터로는 현재 로그인한 유저, 테마, 언어 등이 있다.
props를 사용한 데이터 전달 예시
Context를 사용한 데이터 전달 예시
Context 생성
const ThemeContext = creatContext("light");
Context 저장
< ThemeContext.Provider value="dark" >
Context 접근하기
3-1. Context.Consumer
< ThemeContext.Consumer > {value => < Button theme={value} />}
3-2. useContext(Context)
3-3. contextType - class 컴포넌트
✔ 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것.
✔ context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 쓰는 걸 추천.
✔ context보다 컴포넌트 합성이 더 간단한 해결책일 수도 있다.
✔ Provider의 부모가 렌더링 될 때마다 불필요하게 하위 컴포넌트가 다시 렌더링 되는 문제가 생길 수도 있다. 이를 피하기 위해서는 값을 부모의 state로 끌어올린다.
<Page user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<Link href={user.permalink}>
<Avatar user={user} size={avatarSize} />
</Link>
user와 avatarSize라는 props를 실제로 사용하는 곳은 Avatar 컴포넌트 뿐인데 props를 여러 단계에 걸쳐 보내줘야 한다는 게 번거로워 보일 수 있다. 게다가 위에서 Avatar 컴포넌트로 보내줘야하는 props가 추가된다면 그 또한 중간 레벨에 모두 추가해줘야 한다.
여기서 Avatar 컴포넌트 자체를 넘겨주면 context를 사용하지 않고 이를 해결할 수 있다. 그러면 중간에 있는 컴포넌트들이 user나 avatarSize 에 대해 전혀 알 필요가 없다.
function Page(props) {
const user = props.user;
const userLink = (
<Link href={user.permalink}>
<Avatar user={user} size={props.avatarSize} />
</Link>
);
return <PageLayout userLink={userLink} />;
}
// 이제 이렇게 쓸 수 있다.
<Page user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<PageLayout userLink={userLink} />
// ... 그 아래에 ...
<NavigationBar userLink={userLink} />
// ... 그 아래에 ...
{props.userLink}
이렇게 바꾸면 Link와 Avatar 컴포넌트가 user 와 avatarSize props를 쓴다는 걸 알아야 하는 건 가장 위에 있는 Page 뿐이다.
참고 https://ko.reactjs.org/docs/context.html#gatsby-focus-wrapper