오래전 포스팅에서 클래스형 컴포넌트에서 사용하는 방법을 알아봤고, 이번에는 Hook의 형태로 사용하는 방법을 알아보겠다.
리액트의 Context API는 플러터의 provider와 굉장히 흡사하다.
아마, 플러터의 provider가 리액트의 것을 벤치마킹 한 것 같다.
하지만, provider의 값이 변경되어도 notifyListener()와 같은 함수는 동작하지 않는다. 다시 말해 상태 갱신은 별도이다.
따라서 useState나 dispatch를 provider에 넣어주어야한다.
Context.Provider
//선언, 컴포넌트 외부에 선언한다.
//매개변수에는 기본 값
const ThemeContext = React.createContext(null);
//최상단의 useReducer를 자식 컴포넌트에서 사용할 수 있도록 한다.
const [state, dispatch] = useReducer(themeReducer, initialState);
//컴포넌트
...
return (
//dispatch를 provider를 통해 전달한다.
<ThemeDispatch.Provider value = {dispatch}>
...
</ThemeDispatch.Provider>
//하위 컴포넌트에서의 사용
const OpctionView = () => {
//useContext Hook을 사용해 값을 받아온다.
const themeDispatch = useContext(ThemeDispatch);
const onClick = () => {
dispatch({type:"Dark"};
}
Context.Consumer
useContext 대신 사용할 수 있는 방법이다.
Consumer는 컴포넌트처럼 사용할 수 있으며 여러개의 context를 사용하는 경우 Consumer를 활용한다면 코드는 복잡해지지만 렌더링을 최소화 할 수 있다.
//상위
<ThemeContext.Provider value={{ theme, setTheme }}>
...
</ThemeContext.Provider>
//하위
return (
<ThemeContext.Consumer>
{({ theme, setTheme }) => (
<div>
<h3>{theme}</h3>
</div>
)}
</ThemeContext.Consumer>
...
예제
import React, { useContext, useState } from "react";
const ThemeContext = React.createContext(null);
export default function OpctionView() {
const [theme, setTheme] = useState("Light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div>
<h3>Theme : {theme}</h3>
<ThemeButtonRow></ThemeButtonRow>
</div>
</ThemeContext.Provider>
);
}
function ThemeButtonRow() {
const { theme, setTheme } = useContext(ThemeContext);
const onChange = (value) => {
setTheme(value);
};
return (
<span>
<ThemeContext.Consumer>
{({ theme, setTheme }) => (
<div>
<h3>{theme}</h3>
</div>
)}
</ThemeContext.Consumer>
<button onClick={() => onChange("Dark")}>Dark</button>
<button onClick={() => onChange("Ligth")}>Light</button>
</span>
);
}
하위 컴포넌트가 상위 컴포넌트의 useState를 사용하는 예시이다.
'React > React Basic' 카테고리의 다른 글
[React] 파일 경로를 깔끔하게 정리하기 (3) | 2022.08.29 |
---|---|
[React] 불변성을 쉽게 유지하는 Immer lib (1) | 2021.08.08 |
[리액트] useReducer 이해하기 (0) | 2021.08.07 |
[React] 불필요한 렌더링 최적화하기 (2) | 2021.08.01 |
[React] useMemo와 useCallback (0) | 2021.08.01 |