11. Context API
상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 속성값(Props)을 사용할 수 있다.
가까운 거리에 있는 몇 개의 컴포넌트로 전달할 때는 속성값으로도 충분하지만 많은 수의 하위컴포넌트로 전달할 때는 속성값을 내려주는 코드를 반복적으로 작성해야 한다.
특히 멀리 떨어져 있는 컴포넌트에 데이터를 전달할 때는 중간에 있는 컴포넌트들에도 데이터를 전달하는 코드를 작성해야 한다.
Context API 를 사용하면 좀 더 간편하게 코드를 작성할 수 있다.
1) Context API 사용하기 - Provider와 Comsumer
createContext
를 가져와야 한다.Provider
와 Consumer
컴포넌트가 있다.Provider
에서 value
를 넣어주면 Consumer
에서 그 값을 받아서 처리할 수 있다.Root
까지 올라갔는데 Provider
를 찾지 못하면 기본값으로 설정한 unknown
이 사용된다.Provider
컴포넌트의 value 값이 변경되면 하위의 모든 Consumer
컴포넌트는 다시 렌더링이 된다.import React, { createContext } from 'react';
const UserContext = createContext('unknown'); // 초기값을 넣어서 호출을 해주면 객체가 반환이 된다.
export default function App() {
return (
<div>
<UserContext.Provider value="mike">
<h1>메뉴</h1>
<Profile />
</UserContext.Provider>
</div>
)
}
function Profile() {
return (
<div>
<Greeting />
</div>
)
}
function Greeting() {
return (
<UserContext.Consumer>
{username => <p>{`${username}님 안녕하세요.`}</p>} {/* mike님 안녕하세요. */}
</UserContext.Consumer>
)
}
2) Consumer 말고 더 간편한 useContext 훅 이용하기
function Greeting() {
const username = useContext(UserContext);
return <p>{`${username}님 안녕하세요.`}</p>
}
3) 하위 컴포넌트에서 데이터를 수정하는 방법
Import React,{createContext} from 'react';
const UserContext = createContext({username: 'unKnown', count: 0})
const SetUserContext = createContext(() => {})
export default function App(){
const[user, setUser] = useState({username: 'jessie', count: 0})
return(
<div>
<SetUserContext.Provider value={setUser}>
<UserContent.Provider value={user}>
<Profile />
</UserContent.Provider>
</SetUserContext>
</div>
function Greeting(){
const setUser = useContext(SetUserContext)
const { username, count } = useContext(UserContext)
return (
<>
<p>{`${username}님 안녕하세요.`}</p>
<p>{`카운트 : ${count}`}</p>
<button onClick={() => setUser({ username, count: count + 1 })}> 인사하기
</button>
</>
4) Context API를 사용할 때 주의할 점
username
과 count
를 별도의 상태값으로 관리하고 Provider에 value={{ username, count }}
이런식으로 넣으면 이 컴포넌트가 렌더링이 될 때마다 매번 새로운 객체가 만들어지게 된다. 그래서 value
값이 변경되지 않아도 Consumer는 불필요하게 렌더링이 될 수 있다.username
과 count
속성을 가진 user
라는 객체를 상태값으로 관리하고 value
에는 value={user}
이런 식으로 하나의 객체로 넘기면 매번 새로운 객체가 만들어지지 않는다.