ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React.js] Hooks - useReducer
    Front-End(Web)/React - 프레임워크(React, Next) 2020. 12. 26. 04:16
    반응형

    React 미니 프로젝트들을 수행하다보니, useContext, useReducer 사용을 하라는 미션이 주어졌다. 이 개념에 대한 선행학습을 해봤다.


    📒 useReducer

    useContext와 마찬가지로 통합적인 state 관리를 위한 Hooks다. useReducer는 useState의 대체함수로 생각할 수 있다. 

    Redux의 Reducer, Action 과 그 동작성격이 매우 유사하다고 느껴졌다.

     

    - 문법

    React 공식 사이트의 useReducer 로 카운터를 구현한 예제를 인용했다.

    const initialState = {count: 0};
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return {count: state.count + 1};
        case 'decrement':
          return {count: state.count - 1};
        default:
          throw new Error();
      }
    }
    
    function Counter() {
      const [state, dispatch] = useReducer(reducer, initialState);
      return (
        <>
          Count: {state.count}
          <button onClick={() => dispatch({type: 'decrement'})}>-</button>
          <button onClick={() => dispatch({type: 'increment'})}>+</button>
        </>
      );
    }

     

    먼저, useReducer 함수를 확인해보자. 이는 아래와 같은 기본구조를 가진다.

    const [state, dispatch] = useReducer(reducer, 'initial state');
    • state : 현재 상태값을 가리킨다. useState에서 좌변의 state 값과 동일하다고 보면 된다.
    • dispatch : 액션을 발생시키는 함수를 정의한다. useState에서 좌변의 setter 함수와 유사하다고 보면 된다.
    • reducer : 액션의 type에 따라 state 변경하는 방법을 정의하는 함수. Switch문을 자주 사용한다.
    • initial state : state의 초기값을 설정한다.

    reducer 함수 구조를 알아보자. reducer는 현재상태와 액션(객체)를 파라미터로 받아 새로운 상태를 반환한다.

    const reducer = (state, action) => { switch문 };
    • state : 현재 상태값
    • action : 업데이트와 관련된 정보를 가진 객체
    • switch문 : action.type 에 따른 state 제어방법을 return 한다.

    이처럼, 컴포넌트(예제의 <Counter />) 밖에 업데이트 로직(reducer 함수)이 존재하는 것을 확인할 수 있다.

     

    - 예제분석

    import React, { useReducer } from 'react';
    
    function reducer(state, action){
      return {
        ...state, // state 값을 여기에 복사하고,
        [action.name]: action.value // 값을 덮어씌운다.
      };
    }
    
    const Info = () => {
      const [state, dispatch] = useReducer(reducer, {
        name: '',
        nickname: ''
      });
      
      const {name, nickname} = state;
    
      const onChange = e =>{
        dispatch(e.target);
      }
    
      return (
        <div>
          <div>
            <input name = "name" value={name} onChange={onChange}/>
            <input name = "nickname" value={nickname} onChange={onChange}/>
          </div>
          <div>
            <div>
              이름 : {name}
            </div>
            <div>
              닉네임 : {nickname}
            </div>
          </div>
        </div>
      );
    };
    
    export default Info;

    1. useReducer 함수를 먼저 확인한다. state를 {name, nickname} 객체로 정의했다.

    2. 'initial state'는 모두 빈 String으로 설정한 것을 useReducer 함수에서 확인 가능하다.

    3. 상단의 reducer 함수를 확인해보자. [action.name] : action.value 로, type 인지가 아닌 state 객체를 수정하는 함수다.

    • 컴포넌트의 onChange 함수가 dispatch 동작을 구현하고 있다. action 값을 e.target으로 지정했으므로, action.name은 e.target.name / action.value 는 e.target.value 와 같다.
    • e.target.name 은 해당 <input>의 name 값을, e.target.value 는 해당 <input>의 value 값을 의미한다.
    • 결국 state에 설정된 name, nickname 두 개의 상태와 대칭시켜 value 값을 관리할 수 있게 된다.
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');
        
    const onChangeName = e => {
        setName(e.target.value);
    };
    const onChangeNickname = e => {
        setNickname(e.target.value);
    }

    * useState 로는 2개의 Setter를 사용해야 하는데 반해, 여러 state를 하나의 번들로 관리할 수 있다는 장점이 있다.


    이전의 useContext 보다는 확실히 간단한 Hooks 이다. 그 목적도 useState와 유사하다.

    전역관리를 할 수 있는 점, 또 여러개의 state 관리를 할 수 있다는 장점에서 useReducer 가 사용된다.

    지금까지 미니 프로젝트에서, 한 컴포넌트에서 5개 가량의 state를 관리했고, 실제 앱구현에서 그 양은 더 많을 것이다.

     

    연관된 state의 번들화를 연습한다는 의미로, useReducer 도 적극적으로 사용해봐야겠다.

     

    <출처>
    chanBLOG 님의 github 블로그 : https://chanhuiseok.github.io/posts/react-11/

     

    반응형
Designed by Tistory.