Skip to content

Instantly share code, notes, and snippets.

@pointofpresence
Created May 23, 2020 11:30
Show Gist options
  • Save pointofpresence/ffc701dcf5c492fc27e902deec6b35f7 to your computer and use it in GitHub Desktop.
Save pointofpresence/ffc701dcf5c492fc27e902deec6b35f7 to your computer and use it in GitHub Desktop.

Редьюсеры и хук useReducer

Редьюсеры (или редукторы) – это простые чистые (предсказуемые) функции, которые получают в качестве аргументов предыдущее состояние объекта и объект действия (action), а возвращают обновленное состояние. Другими словами, редьюсеры применяют к состоянию некоторое действие.

function reducer(state, action) {
  // действия редьюсера зависят от типа действия (экшена)
  switch (action.type) {
    // если action.type равен 'LOGIN'
    case "LOGIN":
      // устанавливаем имя юзера и флаг авторизации
      return { username: action.payload.username, isAuth: true };
    case "SIGNOUT":
      return { username: "", isAuth: false };
    default:
      // если действие имеет неизвестный тип, возвращаем текущее состояние
      return state;
  }
}

Редьюсеры – это мощный паттерн управления состоянием, который используется в популярной библиотеке Redux. В то время как локальное состояние компонента регулируется хуком useState, useReducer позволяет управлять данными всего приложения.

Этот хук можно использовать вместе с useContext, чтобы с легкостью передавать данные заинтересованным компонентам.

Вот маленький пример полноценной системы управления состоянием, основанной на связке useReducer + useContext.

const initialState = { username: "", isAuth: false };

function reducer(state, action) {
  switch (action.type) {
    case "LOGIN":
      return { username: action.payload.username, isAuth: true };
    case "SIGNOUT":
      return { username: "", isAuth: false };
    default:
      return state;
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  function handleLogin() {
    dispatch({ type: "LOGIN", payload: { username: "Ted" } });
  }

  function handleSignout() {
    dispatch({ type: "SIGNOUT" });
  }

  return (
    <>
      Current user: {state.username}, isAuthenticated: {state.isAuth}
      <button onClick={handleLogin}>Login</button>
      <button onClick={handleSignout}>Signout</button>
    </>
  );
}

В useReducer передается функция-редуктор и начальное состояние приложения. Он возвращает состояние и функцию dispatch для вызова действий. В dispatch нужно передать объект действия, который будет передан редуктору, тот в свою очередь изменит состояние приложения.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment