리액트 Context

shinetiger·2022년 12월 15일
0

이론정리

목록 보기
12/13

개요

이전에 나는 리액트에 내장되어 있는 상태관리를 쓰지 않고 바로 리덕스나 리코일같은 라이브러리를 사용했기 때문에 Provider는 익숙해도 Context는 그렇지 않았다. 원티드 사전과제에 리액트에 내장되어 있는 라이브러리 말고는 상태관리 라이브러리를 사용할 수 없었으므로 공부하게 되었다.

Context와 Provider

이전 상태관리 라이브러리를 쓸 때 Provider는 단순하게 props를 사용할 수 있게 해주는 ‘영역’ 같은거라고 생각했었다. 그러나 Provider를 쓰기전 Context를 먼저 만들어 주어야 한다.

Context는 객체다

  1. CreateContext() 함수를 사용해서 Context ‘객체’를 만든다.
  2. export를 이용해서 모듈화 시킨다(반드시)
  3. Context라는 객체 안에는 Provider와 Context Consumer(프로바이더에 감싸져서 상태를 사용하는 컴포넌트들을 말한다) 두가지 컴포넌트가 들어 있다.
  4. 초기값을 Context에 넣는다. 이때 데이터를 넣게 해주는 역할을 Provider이다.
export const ColorContext = createContext();

render(
  <ColorContext.Provider value={{ colors }}>
    <App />
  </ColorContext.Provider>,
  document.getElementById("root")
);

Context Provider 에서 데이터 변경하기

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>
  );
}
profile
의문을 질문으로 바꾸는 개발자

0개의 댓글