Как использовать хук useReducer

JavaScript React.js

Автор: Дэйв Седдиа Переводчик: Front-end Xiaozhi Источник: daveceddia

Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статьяGitHub GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.

Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.

Видеть“reducer”Это слово легко напоминаетRedux, но в этой статье не обязательно сначала разбиратьсяReduxпрочитать эту статью. Вместе обсудим"reducer"Что это такое на самом деле, и как это использоватьuseReducerдля управления сложным состоянием в компонентах, и эта новая пара хуковReduxЧто это значит?

какой к черту редуктор

если вы знакомы сReduxили на массивеreduceметод, вы, вероятно, знаете, что такое «редуктор». Если незнакомо,"reducer"Вероятно,2стоимость и возврат1Функция значения означает, что.

Если у вас есть ряд вещей и вы хотите объединить их в один объект. «Функциональное программирование» заключается в использованииArrayизreduceфункция. Например, если у вас есть массив чисел и вы хотите получить сумму всех чисел в массиве, мы можем написатьreducerфункцию и передать ееreduce,Следующим образом:

let numbers = [1, 2, 3];
let sum = numbers.reduce((total, number) => {
    return total + number;
},0)

Если вы не использовали это раньше, это может показаться немного загадочным. Что он делает, так это вызывает функцию для каждого элемента массива, передавая предыдущийtotalи текущий элементnumber.无论你返回什么,都会成为新的total.reduceвторой параметр (в данном случае0)Даtotalначальное значение . В этом примереreduceфункция будет вызываться3Второсортный:

  • передача(0, 1)вернуть1
  • передача(1, 2)вернуть3
  • передача(3, 4)вернуть6

reduceвернуть6, который хранится вsumсередина.

использоватьuseReducerКаким он будет?

Вы потратили половину страницы на объяснениеArrayизreduceфункцию, потому чтоuseReducerпараметр сreduceТо же самое, и работает в основном так же.useReducerперенимать(state, action) => newStateИ вернулся один с текущимstateПарыdispatchМетоды. мы используемuseReducerнаписать приведенный выше пример суммирования.

useReducer((state, acton) => {
  return state + action
}, 0)

useReducerвозвращает содержащий2массив элементов, похожий наuseStateкрюк. Первое — текущее состояние, второе —dispatchМетод следующий:

const [sum, dispatch] = useReducer((state, action) => {
  return state + action
}, 0)

Уведомление,stateМожет быть любым значением, это не обязательно должен быть объект, это может быть число, массив или любой другой тип.

несмотря на то чтоuseReducerпредставляет собой удлиненный крючок, иuseStateявляется основным крючком, ноuseStateфактически реализуетuseReducer. это означаетuseReducerболее родной, вы можете использовать любойuseStateзаменены наuseReducer.

import React, { useReducer } from 'react';

function Counter() {
  // First render will create the state, and it will
  // persist through future renders
  const [sum, dispatch] = useReducer((state, action) => {
    return state + action;
  }, 0);

  return (
    <>
      {sum}

      <button onClick={() => dispatch(1)}>
        Add 1
      </button>
    </>
  );
}

Нажмите кнопкуdispatchстоимость1изaction,Долженactionбудет добавлен к текущему состоянию, а затем компонент повторно отобразится с новым состоянием.

Здесь намеренно показано, что распределениеactionНе следует типичному образцу Redux{type: "INCREMENT BY"、value: 1}или что-то подобное. Мир крючков — новый мир: стоит подумать, считаете ли вы старые модели ценными и хотите ли вы их сохранить, или же вы готовы их изменить.

несколько более сложных примеров

Давайте посмотрим ближе к типичномуRedux reducerпример. Создайте компонент для управления списком покупок, здесь мы будем использовать другой хук:useRef.

Сначала импортируйте два хука

import React, { useReducer, useRef } from 'react';

затем создайте настройкуrefа такжеreducerс компонент.refСохраните ссылку на форму, чтобы мы могли извлечь ее значение.

function ShoppingList() {
  const inputRef = useRef();
  const [items, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      // do something with the action
    }
  }, []);

  return (
    <>
      <form onSubmit={handleSubmit}>
        <input ref={inputRef} />
      </form>
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            {item.name}
          </li>
        ))}
      </ul>
    </>
  );
}

Обратите внимание, что в этом случае наше "state«Это массив. Мы проходимuseReducerВторой параметр инициализирует его пустым массивом и изменяет его сreducerФункция возвращает массив.

useRef Hook

useRefкрючокDOMУзлы создают постоянные ссылки. передачаuseRefсоздаст пустой узел. Возвращаемый объект имеетcurrentсвойство, поэтому в приведенном выше примере мы можем использоватьinputRef.currentПолучите доступ к входному узлу DOM. если вы знакомы сReact.createRef(), работает очень похоже.

но,useRefВозвращаемый объект — это не просто способ хранения ссылки на DOM. Он может содержать любое значение, характерное для этого экземпляра компонента, и сохраняется между рендерингами.

useRefМожет использоваться для создания универсальных переменных экземпляра, как и при использованииthis.whatever = valueизReactКомпоненты класса одинаковы. Единственная проблема в том, что запись в него считается «побочным эффектом», поэтому мы не можем изменить его во время рендеринга.useEffectЕго можно изменить только в хуке.

назадuseReducerПример

Мы используем форму для обработки пользовательского ввода и нажимаем Enter, чтобы отправить благодарность. Теперь написатьhandleSubmitфункция, которая в основном заключается в добавлении элемента в список, а также в обработкеreducerсерединаaction.

function ShoppingList() {
  const inputRef = useRef();
  const [items, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case 'add':
        return [
          ...state,
          {
            id: state.length,
            name: action.name
          }
        ];
      default:
        return state;
    }
  }, []);

  function handleSubmit(e) {
    e.preventDefault();
    dispatch({
      type: 'add',
      name: inputRef.current.value
    });
    inputRef.current.value = '';
  }

  return (
    // ... same ...
  );
}

существуетreducerФункция в основном оценивает две ситуации: одна используется дляaction.type==='add'случай, есть случай по умолчанию.

когдаaction.typeдляadd, он возвращает новый массив, содержащий все старые элементы и новый элемент в конце.

Здесь следует отметить, что мы используем массивlengthУдобно для демонстрации в качестве автоматически увеличивающегося идентификатора, но это ненадежно для реального приложения, поскольку может привести к дублированию идентификаторов и ошибкам. (Лучше используйте библиотеку, например uuid, или пусть сервер сгенерирует уникальный идентификатор!)

Вызывается, когда пользователь нажимает клавишу Enter в поле вводаhandleSubmitфункция, поэтому нам нужно вызватьpreventDefaultчтобы избежать перезагрузки всей страницы, когда это произойдет. потомdispatchраспространять одинaction.

удалить пункт

Теперь давайте посмотрим, как удалить элементы из списка.

добавить удаление в проект<button>, нажмите кнопку, чтобы отправить, он отправит действиеtype === "remove"и индекс удаляемого элемента.

Тогда нам просто нужноreducerобрабатыватьaction

function ShoppingList() {
  const inputRef = useRef();
  const [items, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case 'add':
        // ... same as before ...
      case 'remove':
        // keep every item except the one we want to remove
        return state.filter((_, index) => index != action.index);
      default:
        return state;
    }
  }, []);

  function handleSubmit(e) { /*...*/ }

  return (
    <>
      <form onSubmit={handleSubmit}>
        <input ref={inputRef} />
      </form>
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            {item.name}
            <button
              onClick={() => dispatch({ type: 'remove', index })}
            >
              X
            </button>
          </li>
        ))}
      </ul>
    </>
  );
}

Упражнение: очистить список

Попробуйте добавить функцию: добавьте кнопку, которая очищает список.

существует<ul>Вставьте кнопку выше и дайте ейonClick prop, распределитеaction ,typeдля"clearдействие, а вreducerМетод выполняет действие по очистке списка.

может быть впередиCodeSandboxвыполнено на базе.

Редукс умрет?

большинство людей видятuseReducerхуки, React теперь имеет встроенныйreducer,она имеетContextпередавать данные, так что можно подуматьReduxУмрет ли он из-за этого?Вот несколько мнений автора оригинала.

Автор не считаетuseReducerубьетRedux. Реактивный крюк расширяетсяReactспособности в государственном управлении, поэтому использовал быReduxситуация снижается.

ReduxВсе же лучше, чем Context+useReducerКомбинация Redux делает больше, у нее есть Redux DevTools для отладки, настраиваемое промежуточное ПО и целая экосистема связанных библиотек, конечно, Redux часто используется во многих местах, но он по-прежнему мощный.

ReduxПредоставляет глобальное хранилище, в котором данные приложения могут храниться централизованно.useReducerЛокализованы для определенных компонентов. Однако ничто не мешает нам использоватьuseReducerа такжеuseContextСобери свой миниredux. Если вы хотите сделать это, и это соответствует вашим потребностям, сделайте это!

Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.

оригинал:

Woohoo. Робин попросил IE о допуске. /react-user E…

общаться с

Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.