개발 🐾/ReactJS

초간단 useContext + useReducer

JOTOKKI 2021. 7. 2. 17:38
728x90

 

useContext에서 useReducer를 통해 redux처럼 사용해 보도록 하겠습니다. 

기능은 간단하게 admin이라는 state를 가지고 true일 때 false일 때 문구만 다르게 출력하도록 하였습니다. 

 

예전에 useContext가 redux를 대체할 수 있을 만큼 편리하다고 하여 작은 프로젝트 하나를 redux를 사용하지 않고 useContex만 사용해서 만들어본 적이 있다. 

 

먼저 context를 작성합니다.

import { createContext, useReducer } from "react";

// reducer
const initialState = {
    admin: false
}

const reducer = (state, action) => {
    switch(action.type) {
        case 'SET_ADMIN': 
        return {
            ...state,
            admin: !state.admin
        }
        default: 
            throw new Error("Doesn't have action type");
    }
}

// context
export const UserContext = createContext(null);

// provider
export const UserProvider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, initialState);
    const { admin } = state;
    return (
        <UserContext.Provider value={{ dispatch, admin }}>
            { children }
        </UserContext.Provider>
    )
}

 

SET_ADMIN을 호출하는 경우 admin의 상태 값을 반대로 set 하도록 설정하였습니다. 

provider를 통해 자식 컴포넌트에게 value 값으로 state와 dispatch를 전달해 줍니다.

 

components디렉터리를 생성하고 UserButton파일과 UserInfo파일을 생성합니다. 

App에서 두 파일을 모두 좀 전에 생성했던 Provider로 감싸줘야 합니다.  

// component
import UserInfo from './components/UserInfo'
import UserButton from './components/UserButton'

// provider
import { UserProvider } from './_context/UserContext'

function App() {
  return (
    <div className="App">
      <UserProvider>
        <UserButton/>
        <UserInfo/>
      </UserProvider>
    </div>
  );
}

export default App;

 

이렇게 하면 UserProvider 자식 요소들은 전달받은 value 값을 사용할 수 있습니다. 

사용할 때에는 useContext를 사용합니다. 

// components/UserInfo.js
import { useContext } from 'react';
import { UserContext } from '../_context/UserContext';
function UserInfo() {
    const { admin } = useContext(UserContext);
    return (
        <div>
            <p>{ admin ? "관리자입니다." : "사용자입니다."}</p>
        </div>
    )
}
export default UserInfo
// components/UserButton.js
import { useContext } from 'react';
import { UserContext } from '../_context/UserContext';

function UserButton() {
    const { admin, dispatch } = useContext(UserContext);
    const handleToggleUser = () => {
        dispatch({ type: 'SET_ADMIN' })
    }
    return <button onClick={handleToggleUser}>{admin ? "사용자" : "관리자"}로 전환하기</button>
}
export default UserButton

 

이렇게 하면 다음과 같이 잘 동작되는 것을 확인 할 수 있습니다. 

 

 

개인적인 생각

확실히 redux처럼 복잡한 setting을 거치지 않고 바로 사용할 수 있는 점이 좋긴 했습니다. 

옛날 순수한 redux만 계속해서 사용해야 한다면, 매력적인 대안이 될 수 있었겠지만 

redux-actions, redux-toolkit, redux-saga 등의 더 편하게 사용할 수 있는 라이브러리들이 추가로 생겨나면서 

context만으로 모든걸 처리하는 것이 되려 더 불편하게 느껴졌습니다.

단순한 sample은 상관없지만 기존 플젝은 이거보단 규모가 있었기에, 결국엔 redux로 다시 바꾸는 작업을 했습니다.😭

물론 아직 실력이 미천한 소인의 생각일 뿐입니다.😑

반응형