본문 바로가기
프로그래밍/React

[React] useReducer

by YuminK 2023. 11. 30.

useReducer

useReducer is a React Hook that lets you add a reducer to your component.

const [state, dispatch] = useReducer(reducer, initialArg, init?)

 

Parameters 

  • reducer: The reducer function that specifies how the state gets updated. It must be pure, should take the state and action as arguments, and should return the next state. State and action can be of any types.
  • initialArg: The value from which the initial state is calculated. It can be a value of any type. How the initial state is calculated from it depends on the next init argument.
  • optional init: The initializer function that should return the initial state. If it’s not specified, the initial state is set to initialArg. Otherwise, the initial state is set to the result of calling init(initialArg).

Returns 

useReducer returns an array with exactly two values:

  1. The current state. During the first render, it’s set to init(initialArg) or initialArg (if there’s no init).
  2. The dispatch function that lets you update the state to a different value and trigger a re-render.

Reference 

useReducer(reducer, initialArg, init?) 

Call useReducer at the top level of your component to manage its state with a reducer.

 

Parameters 

  • reducer: The reducer function that specifies how the state gets updated. It must be pure, should take the state and action as arguments, and should return the next state. State and action can be of any types.
  • initialArg: The value from which the initial state is calculated. It can be a value of any type. How the initial state is calculated from it depends on the next init argument.
  • optional init: The initializer function that should return the initial state. If it’s not specified, the initial state is set to initialArg. Otherwise, the initial state is set to the result of calling init(initialArg).

Returns 

useReducer returns an array with exactly two values:

  1. The current state. During the first render, it’s set to init(initialArg) or initialArg (if there’s no init).
  2. The dispatch function that lets you update the state to a different value and trigger a re-render.

uesReducer는 useState와 유사한데, 함수를 따로 뺴서 핸드러를 제공할 수 있다. 여러 이벤트로 나누어서 처리할 수 있는데 비슷한 기능끼리 묶기에 적합해 보인다. 컴포넌트 외부에서 핸들러를 정의할 수 있다. 

 

이렇게 정의한 다음에

 

function reducer(state, action) {

  // ...

}

 

다음 상태를 계산하고 반환할 함수를 만들면 된다. Switch 문을 만드는 것과 유사하다고 생각하면 된다. 

 

function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      return {

        name: state.name,

        age: state.age + 1

      };

    }

    case 'changed_name': {

      return {

        name: action.nextName,

        age: state.age

      };

    }

  }

  throw Error('Unknown action: ' + action.type);

}

 

관례적으로 액션을 정의하는 type 속성을 추가한 오브젝트를 넘기는 편이다. 다음 상태를 처리하기 위한 최소한의 정보를 넘겨야 한다.

 

function Form() {

  const [state, dispatch] = useReducer(reducer, { name: 'Taylor', age: 42 });

  

  function handleButtonClick() {

    dispatch({ type: 'incremented_age' });

  }

 

  function handleInputChange(e) {

    dispatch({

      type: 'changed_name',

      nextName: e.target.value

    });

  }

  // ...

 

액션 타입의 이름은 컴포넌트에 local로 반영된다. 각 액션은 단일 동작으로 구성된다(여러 정보가 한번에 변경될 지라도) 상태는 read-only이다. 데이터를 수정하지 말고 생성해라. 초기값 넣을 떄, 함수 넣으면 매 렌더마다 처리가 된다. (주의)

 

function createInitialState(username) {

  // ...

}

 

function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, createInitialState(username));

  // ...

 

매번 호출되는 것을 막고 싶다면, 이런 식으로 쓰면 된다.

 

function createInitialState(username) {

  // ...

}

 

function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, username, createInitialState);

  // ...

 

만약 초기화 함수가 인자를 받지 않는다면 중간에 null을 입력해주자. 

 

바뀐 값은 다음 렌더부터 적용된다. 값을 수정하지 말고 새로 생성해라. 

 

첫 번째 방식은 매번 렌더시마다 함수를 호출한다. (주의)

 

// 🚩 Wrong: calls the handler during render

return <button onClick={handleClick()}>Click me</button>

 

// Correct: passes down the event handler

return <button onClick={handleClick}>Click me</button>

 

// Correct: passes down an inline function

return <button onClick={(e) => handleClick(e)}>Click me</button>

 

https://react.dev/reference/react/useReducer

'프로그래밍 > React' 카테고리의 다른 글

Nextjs 정리  (0) 2024.01.10
[React] createContext  (0) 2023.11.29
[React] useContext  (0) 2023.11.29
[React] forwardRef  (0) 2023.11.29
[React] memo  (1) 2023.11.29

댓글