본문 바로가기
FE Development/React

useContext, useReducer

by 개발자 데이빗 2021. 10. 7.

 useContext 와 useReducer를 활용한 상태관리

1. useContext

기존의 컴포넌트 간에 데이터를 전달하려면 props를 이용해야 한다.

props는 부모 자식 관계에서 데이터를 전달한다.

A, B, C 컴포넌트가 각각 부모자식 관계인 경우 A 에서 C 컴포넌트로 데이터를 보내주려면 중간 B 컴포넌트를 거쳐야 한다.

컴포넌트가 많아져 구조가 깊어질 경우 비효율적이다.

이를 해결하기 위해 주로 사용된 라이브러리에 여러가지 전역 상태 관리 라이브러리가 있다.

주로 사용하였던 Redux를 대신 할 useContext와 useReducer에 대해 알아보았다.

 

context는 한때 React 공식문서에서 사용하지 말라고 얘기했었으나 React 팀에서 context api를 새롭게 되살려 내고, React.createContext와 useContext가 나오며 활발히 사용되고 있다.

 

2. useReducer (createDataContext)

 

Context와 Provider를 생성할 모듈(createDataContext)을 만든다.

actions에 dispatch를 바운딩 해주고 state와 함께 provider에 주입한다.

defaultValue는 Redux의 initialState와 같다.

Context.Provider 하위에 상태관리를 할 컴포넌트를 두고 사용한다. ( 전역 상태관리를 위해 최상위 컴포넌트 )

3. Action, Reducer 

import React, { useReducer } from "react";

export default (reducer, actions, defaultValue) => {
  const Context = React.createContext(defaultValue);

  const Provider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, defaultValue);
    const boundActions = {};
    for (let key in actions) {
      if (actions.hasOwnProperty(key)) {
        boundActions[key] = actions[key](dispatch);
      }
    }

    return (
      <Context.Provider value={{ state, ...boundActions }}>
        {children}
      </Context.Provider>
    );
  };

  return {
    Context,
    Provider,
  };
};

 

- Reducer

export default (state, action) => {
  switch (action.type) {
    case "action_type":
      return ;
    default:
      return state;
  }
}

 

- Actions

const myAction = (dispatch) => async () => {
  dispatch({
    type: "my_action",
    payload: {
      action: true,
    },
  });
};

 

- createDataContext

export const { Context, Provider } = 
	createDateContext(myReducer, {...actions}, {...defaultValue});

 

 

사용할 컴포넌트에서 useContext를 호출해 사용한다.

import React, { useContext } from 'react';
import { AppContext } from '....../AppContext';
import { AppProvider } from '....../AppProvider';

const App = () => {
	const { 
    state : {...},
    action1,
    action2,
    action3
    } = useContext(AppContext);
    
	return(
    	<React.Fragment>
        </React.Fragment>
        )
};

export default (
 <AppProvider>
   <App />
 </AppProvider>
)

 

 

댓글