이전에 나는 리액트에 내장되어 있는 상태관리를 쓰지 않고 바로 리덕스나 리코일같은 라이브러리를 사용했기 때문에 Provider는 익숙해도 Context는 그렇지 않았다. 원티드 사전과제에 리액트에 내장되어 있는 라이브러리 말고는 상태관리 라이브러리를 사용할 수 없었으므로 공부하게 되었다.
이전 상태관리 라이브러리를 쓸 때 Provider는 단순하게 props를 사용할 수 있게 해주는 ‘영역’ 같은거라고 생각했었다. 그러나 Provider를 쓰기전 Context를 먼저 만들어 주어야 한다.
export const ColorContext = createContext();
render(
<ColorContext.Provider value={{ colors }}>
<App />
</ColorContext.Provider>,
document.getElementById("root")
);
Context Provider 자체적으로 Context 데이터를 변경할 수 없다.
그러니 Context Provider를 렌더링 시키는 상태를 가진 컴포넌트를 만들어야 한다. (상태가 변경되면 새로운 Context data를 가지게되고, 그러면 Provider도 재 렌더링 하게 된다)
리액트는 단방향이므로, 상태를 가지려면 Context Provider보다 상위에 있어야 한다.
const ColorContext = createContext();
//Context Consumer에서 쓰인다
export const useColors = () => useContext(ColorContext);
//모듈화된 ColorProvider는 index에서 쓰인다
export default function ColorProvider({ children }) {
const [colors, setColors] = useState(colorData);
const addColor = (title, color) =>
setColors([
...colors,
{
id: v4(),
rating: 0,
title,
color
}
]);
const rateColor = (id, rating) =>
setColors(
colors.map(color => (color.id === id ? { ...color, rating } : color))
);
const removeColor = id => setColors(colors.filter(color => color.id !== id));
//TS로 했으면 오류났을듯
return (
<ColorContext.Provider value={{ colors, addColor, removeColor, rateColor }}>
{children}
</ColorContext.Provider>
);
}