ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • useState 인자로 함수 전달하기 (+useReducer)
    React 2022. 4. 28. 23:55
    728x90

    useState 인자로 함수 전달하기

    이상하게도 지금까지 한 번도 useState에 인자로 함수를 전달하는 것을 생각하지 못하였다. 

    그러던 중 리액트 성능 테스트를 하기 위해 많은 양의 데이터를 화면에 출력해야 하는 상황이 생겨 useState 인자로 많은 데이터를 생성하는 함수를 넣어보았다. 

    useState의 인자로 함수를 전달하는 경우 + 추가로 useReducer의 인자로 함수를 전달하는 경우를 정리해보자!

    (해당 내용 출처 : 리액트를 다루는 기술 개정판/ 지은이: 김민준) 


    useState 인자로 함수를 전달하는 경우

    useState 초기값으로 함수를 전달할 수 있는데 아래 2가지 경우에 따라 다르게 동작시킬 수 있다.

    const testFuc = () => {
    	...
    }
    
    // #1
    const [data, setData] = useState(testFuc())
    
    
    // #2
    const [data, setData] = useState(testFuc)

    #1의 경우

    - 해당 컴포넌트가 리랜더링 될 때마다 함수가 호출됨

    #2의 경우

    - 함수의 형태로만 전달하면 Didmount와 같이 컴포넌트가 처음 랜더링 되는 시점에서만 함수가 호출됨.

    나의 경우에는 해당 로직이 APP 컴포넌트에 위치해 있으며 처음 랜더링된 시점에서만 많은 양의 데이터가 필요하기에 #2와 같이 사용하였다.


    useReducer 인자로 함수를 전달하는 경우

    위와 같이 useReducer 초기값으로 함수를 전달하는 경우를 살펴보자.
    아래 2가지 방법이 있다.

    const todoReducer = (todos, action) => {
      switch (action.type) {
        case 'INSERT':
          return todos.concat(action.todo);
        case 'REMOVE':
          return todos.filter((todo) => todo.id !== action.id);
        case 'TOGGLE':
          return todos.map((todo) =>
            todo.id === action.id ? { ...todo, checked: !todo.checked } : todo
          );
        default:
          return todos;
      }
    };
    
    // #1
    const [todos, dispatch] = useReducer(todoReducer, createBulkTodos());
    
    // #2
    const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);

    #1의 경우

    - 일반적인 방법으로 useReducer를 두번째 인자, 초기 값으로 전달하는 방법.

    - 보통 state 자체를 넣어주는 경우가 많긴 하다.

    #2의 경우

    - 보통 useReducer는 두번째 인자로 초기값을 전달한다,
    여기서는 두번째 인자로 undefined를 세번째 인자로 초기 값을 생성하는 함수를 전달하였다.

    사실상 1, 2번 경우 모두 동일하게 동작하는 것으로 보인다.
    useState 예제와 달리 접근성?의 차이가 있지 않나라고 생각한다.

    사실상 useReducer의 두번째 인자로 초기 값을 전달하는 것으로 모두 알고 있기에 1번과 같이 전달하면 정확히 어떤 값을 전달하고 싶은지 애매모호해지지 않나라고 생각한다. 반면에 2번과 같이 초기값으로 확실한 undefined를 명시하고 이후 state를 생성하는 함수를 전달하는 방식을 취하는게 더 useReducer를 useReducer 답게 사용하는 방법이지 않을까 생각한다. (굉장히 주관적)

    실제로 useReducer에서는 세번째 인자로 state를 생성하는 함수를 받을 수 있으니 말이다!


    위 useState, useReducer 예제는 모두 같은 역할을 하지만
    useReduer로 상태를 업데이트하면 해당 로직을 분리시킬 수 있고,
    굉장히 많은 상태를 다루는 경우 useState보다 useReducer를 사용하는게 개인적으로 편리했다고 생각한다.
    추가되는 값에 따라 계속 어떠한 상태를 추가하는 로직보다는 reducer 함수에 추가시킴으로써 확장성 측면에서도 굉장히 큰 이점이 있다.

    수많은 데이터를 다뤄야할 경우 useReducer가 확실히 이점이 있다고 생각하지만 규모가 크지 않다면 굳이
    useReducer를 사용하지 않아도 될 것 같다. 책에서는 성능은 2가지 모두 큰 차이가 없다고 하니 말이다.


    출처 및 참고

    리액트를 다루는 기술 개정판 (지은이 김민준)

    728x90
Designed by Tistory.