[React.js] React Context

2024. 3. 25. 16:01Web/React.js

React Context 란

컴포넌트간의 데이터를 전달하는 또 다른 방법

기존의 Props가 가지고 있던 단점을 해결할 수 있음

Props의 단점은 부모에서 자식으로만 데이터를 전달할 수 있었다

App → ChildA → ChildB 이런 식의 부모자식을 갖는 컴포넌트가

App 컴포넌트에서 바로 ChildB에게 Props를 전달할 수가 없고

ChilA를 거쳐서 Props를 전달해야 했다.

 

최상위 컴포넌트에 존재하는 함수들을

Context (데이터 보관소 {객체}) 보관해 놓으면

Props를 이용하지 않고 Context를 통해서 필요한 데이터를 직통으로 공급해 줄 수 있다.

 

Context 사용하기

※특별한 경우가 아니면 Context함수는 컴포넌트 외부에 선언한다.

export const TodoContext = createContext();

function App() {
return (
    <div className="App">
      <Header />
      <TodoContext.Provider>
        <Editor onCreate={onCreate} />
        <List todos={todos} onUpdate={onUpdate} onDelete={onDelete} />
      </TodoContext.Provider>
    </div>
  );

 

TodoContext.Provider 안에 있는 컴포넌트 들은 모두다 TodoContext의 데이터를 공급 받을수 있다.

<TodoContext.Provider value={{ todos, onCreate, onUpdate, onDelete }}>
   <Editor />

이렇게 데이터를 전달을 한다.

데이터를 받고자 하는 컴포넌트에

import { useState, useRef, useContext } from "react";
import { TodoContext } from "../App";

const Editor = () => {
  const { onCreate } = useContext(TodoContext);

임포트를 해서 데이터를 가지고오면 된다.

Context 분리하기

TodoStateContext                TodoDispatchContext

변경될수 있는 값                  변경되지 않는 값

todos                                    onCreate, onUpdate, onDelete

 

이렇게 Context를 분리하게 되면 TodoStateContext의 todos가 변경되더라도

TodoDispatchContext는 변경되지 않기때문에 함수들은 리렌더링 되지않는다.

 

import {  useMemo } from "react";
export const TodoStateContext = createContext();
export const TodoDispatchContext = createContext();

 

const memoizedDispach = useMemo(() => {
    return { onCreate, onUpdate, onDelete };
  }, []);

  return (
    <div className="App">
      <Header />
      <TodoStateContext.Provider value={todos}>
        <TodoDispatchContext.Provider value={memoizedDispach}>
          <Editor />
          <List />
        </TodoDispatchContext.Provider>
      </TodoStateContext.Provider>
    </div>
  );
}

 

useMemo를 임포트 해주고 TodoStateContext, TodoDispatchContex 생성해준다음

TodoStateContext.Provider 는 todos만 value로 전달을해준다

TodoDispatchContex.Provider에는 useMemo로 생성한 memoizedDispach를 전달해주면

최초 마운트 이후 리렌더링이 되지 않는다.

반응형