Context API 필요성
만약 3번째 컴포넌트(Level3)에서 속성값을 받고자 한다면 Level1, Level2를 거쳐서 값을 받아야 한다.
중간 컴포넌트에서는 해당 속성값을 사용하지 않더라도, 그 다음 컴포넌트에서 사용한다면 단순히 전달만을 위해서 속성값을 받아야 하므로 비효율적이다.
import React from "react";
const App = () => <Level1 message="메시지" />;
const Level1 = ({ message }) => <Level2 message={ message } />;
const Level2 = ({ message }) => <Level3 message={ message } />;
const Level3 = ({ message }) => <div>Level3: { message }</div>;
export default App;
createContext
훅으로 context를 만들어주면 상위 컴포넌트를 거치지 않고도 어느 컴포넌트든 value에 접근할 수 있다.
.Consumer
는 상위로 올라가면서 가까운 .Provider
를 찾는다. 관련 Provider가 없으면 default 값을 사용한다.
import React, { createContext } from "react";
const MessageContext = createContext('default message'); // default값. 비워놔도 됨.
const App = () => (
// value가 변경될 경우 하위 모든 컴포넌트를 다시 랜더링
<MessageContext.Provider value="메시지">
<Level1 />
</MessageContext.Provider>
);
const Level1 = ({ message }) => <Level2 message={ message } />;
const Level2 = ({ message }) => <Level3 message={ message } />;
const Level3 = ({ message }) => (
<div>
<MessageContext.Consumer>
{ message => `Level3: ${ message }` }
</MessageContext.Consumer>
</div>
);
export default App;
useContext 훅 사용하기
(그런데 이제 고차 컴포넌트를 곁들인)
useContext
는 consumer 역할이다. 따라서 useContext
훅을 사용한다면 .Consumer
를 사용할 필요가 없다.
import React, { createContext, useContext } from "react";
const MessageContext = createContext('default message');
const App = () => (
<MessageContext.Provider value="메시지">
<Level2Wrapper />
</MessageContext.Provider>
);
const Level2Wrapper = () => {
const message = useContext(MessageContext);
return (
<div>
<Level2 message={ message }></Level2>
</div>
);
};
const Level2 = ({ message }) => <div>Level2: { message }</div>;
export default App;
코드가 간결해져 가독성이 좋아졌다.