Рубрики
Без рубрики

Состояние обработки в реакции: четыре неизменных подхода к рассмотрению

Дом Кори Возможно, самая распространенная пункт путаницы в реакции сегодня: государство. Представьте, что у вас есть форма для редактирования пользователя. Обычно создать один обработчик изменений для обработки изменений на все поля формы. Это может выглядеть что-то подобное: UpdateState (событие) {const {name, значение}

Автор оригинала: FreeCodeCamp Community Member.

Дом Кори

Возможно, самая распространенная пункт путаницы в реакции сегодня: государство.

Представьте, что у вас есть форма для редактирования пользователя. Обычно создать один обработчик изменений для обработки изменений на все поля формы. Это может выглядеть что-то подобное:

updateState(event) {
 const {name, value} = event.target;
 let user = this.state.user; // this is a reference, not a copy...
 user[name] = value; // so this mutates state ?
 return this.setState({user});
}

Концерн находится на линии 4. Строка 4 фактически мутирует состояние, потому что пользовательская переменная является Ссылка указать. Состояние реагирования следует рассматривать как неизменное.

От Реагистрировать документы :

Почему?

  1. Установка партии работают за кулисами. Это означает, что ручная мутация состояния может быть переопределена при обработке SetState.
  2. Если вы объявите метод SECCOMPONENTUPDATE, вы не можете использовать проверку внутри, потому что Ссылка на объект не изменится Отказ Таким образом, подход выше имеет потенциальное воздействие на производительность.

Итог : Пример выше часто работает хорошо, но, чтобы избежать краевых чехлов, лечить состояние как неизменного.

Вот четыре способа лечения состояния как неизмеренное:

Подход № 1: Object.Assign

Объект.assign Создает копию объекта. Первый параметр – это цель, то вы указываете один или несколько параметров для свойств, которые вы хотели бы включить. Таким образом, исправление приведенного выше примера включает в себя простое изменение в строку 3:

updateState(event) {
 const {name, value} = event.target;
 let user = Object.assign({}, this.state.user);
 user[name] = value;
 return this.setState({user});
}

В строке 3 я говорю: «Создайте новый пустой объект и добавьте все свойства на этом .State.user к этому». Это создает отдельную копию пользовательского объекта, который хранится в состоянии. Теперь я в безопасности, чтобы мутировать объект пользователя в строке 4 – это совершенно отдельный объект от объекта в состоянии.

Убедитесь, что Polyfill Object.assign, так как это неподдерживаемый в IE. и не трансформирован Бабел . Четыре варианта для рассмотрения:

  1. Объект-назначение
  2. Документы MDN
  3. Babel Polyfill
  4. Polyfill.io

Подход № 2: Распространение объекта

Распространение объекта в настоящее время является Этап 3 особенность и может быть транспортирован Бабел . Этот подход более лаконичен:

updateState(event) {
 const {name, value} = event.target;
 let user = {...this.state.user, [name]: value};
 this.setState({user});
}

В строке 3 я говорю, «используйте все свойства. Таким образом, этот подход работает аналогично подходу на объект. Назначение, но имеет два преимущества:

  1. Ни один полифилл не требуется, Так как Бабел может транпиливать
  2. Более краткий

Вы можете даже использовать разрушительную и настраивать, чтобы сделать это одноклассник:

updateState({target}) {
 this.setState({user: {...this.state.user, [target.name]: target.value}});
}

Я изуродован событие в подписи метода, чтобы получить ссылку на Event.target. Затем я объявляю, что государство должно быть установлено на копию этого .state.user с соответствующим свойством, установленным на новое значение. Мне нравится, насколько это зависит. В настоящее время это мой любимый подход к написанию обработчиков изменения. ?

Эти два подхода выше являются наиболее распространенными и простыми способами обрабатывания неизменного состояния. Хотите больше энергии? Проверьте два других варианта ниже.

Подход № 3: хелпер неизменности

Несмотря на молчание это удобная библиотека для мутации копии данных без изменения источника. Эта библиотека предложена в Реагические документы Отказ

// Import at the top:
import update from 'immutability-helper';

updateState({target}) {
 let user = update(this.state.user, {$merge: {[target.name]: target.value}});
 this.setState({user});
}

На строке 5 я звоню слиянием, что это Один из многих команд предоставляется иммутабельностью-помощником. Многое нравится Object.Ascign, я передаю его целевой объект в качестве первого параметра, то укажите свойство, которое я хотел бы объединить.

Там гораздо больше для негодования, чем это. Он использует синтаксис, вдохновленный языком запроса MongoDB и предлагает Разнообразие мощных способов работы с неизменными данными Отказ

Подход № 4: Immuteable.js

Хотите программически соблюдать неизменность? Рассмотрим Immutable.js Отказ Эта библиотека предоставляет неизменные структуры данных.

Вот пример, используя неизменяемую карту:

// At top, import immutable
import { Map } from 'immutable';

// Later, in constructor...
this.state = {
  // Create an immutable map in state using immutable.js
  user: Map({ firstName: 'Cory', lastName: 'House'})
};

updateState({target}) {
 // this line returns a new user object assuming an immutable map is stored in state.
 let user = this.state.user.set(target.name, target.value);
 this.setState({user});
}

Существует три основных шага выше:

  1. Импорт неизменен.
  2. Установите состояние на неизменной карте в конструкторе
  3. Используйте метод SET в обработчике Изменения, чтобы создать новую копию пользователя.

Красота Immutable.js: Если вы попытаетесь использовать состояние штата напрямую, он не будет потерпеть неудачу Отказ С другими подходами выше, легко забыть, и отреагируйте, не предупреждают вас, когда вы напрямую мутатет.

Нисходящие неизменные?

  1. Раздувать Отказ Immuteable.js добавляет 57 тыс. Долларов до вашего пакета. Учитывая библиотеки, такие как Preact может заменить реагирование только в 3K Трудно принять.
  2. Синтаксис Отказ Вы должны ссылаться на объектные свойства с помощью строк и вызовов метода, а не напрямую. Я предпочитаю User.name over user.get («Имя»).
  3. Yattl (Еще одна вещь, чтобы узнать) – Любой, кто присоединяется к вашей команде, должен узнать еще один API для получения и установки данных, а также новый набор данных DataTypes.

Пара других интересных альтернатив для рассмотрения:

Предупреждение: следите за вложенными объектами!

Вариант № 1 и № 2 выше (Object.Assign и Object Spread) Только сделать неглубокий клон. Так что, если ваш объект содержит вложенные объекты, Эти вложенные объекты будут скопированы посредством ссылки вместо по стоимости . Поэтому, если вы измените вложенный объект, вы мутируете оригинальный объект. ?

Будь хирургическим о том, что вы клонируете. Не закрывайте все вещи. Клонировать объекты, которые изменились. Хельпер неизменности (упомянутый выше) делает это легко. Как и альтернативы, как потрясающий , upteep или Долгий список альтернатив .

Вы можете быть соблазнены достичь глубоких инструментов слияния, таких как Глубокий клон или lodash.merge , но Избегайте слепого глубокого клонирования Отказ

Вот почему:

  1. Глубоко клонирование дорого.
  2. Глубоко клонирование, как правило, расточительно (вместо этого только клонируется, что на самом деле изменилось)
  3. Глубокие клонирование вызывает ненужные рендеры, поскольку реагирование считает, что все изменилось, когда на самом деле изменилось только определенный дочерний объект.

Благодаря Дэну Абрамову за предложения, которые я упомянул выше:

Я не думаю, что CLONDEEP () – хорошая рекомендация. Это может быть очень дорого. Только копируйте детали, которые фактически изменились. Библиотеки, такие как Immutability-Helper ( https://t.co/yadmmpioo8 ), updeep ( https://t.co/p0mzd19hcd ) или Immer ( https://t.co/Vyra6cd4ip ) Помогите с этим.

Последний совет: рассмотрите возможность использования функционального SetState

Еще одна морщина может укусить вас:

Поскольку STATSTATE CONSTS BATCHED, код, как это приводит к ошибке:

updateState({target}) {
 this.setState({user: {...this.state.user, [target.name]: target.value}});
 doSomething(this.state.user) // Uh oh, setState merely schedules a state change, so this.state.user may still have old value
}

Если вы хотите запустить код после завершения вызова SetState, используйте форму обратного вызова STETSTATE:

updateState({target}) {
   this.setState((prevState) => {
     const updatedUser = {...prevState.user, [target.name]: target.value}; // use previous value in state to build new state...     
     return { user: updatedUser }; // And what I return here will be set as the new state
   }, () => this.doSomething(this.state.user); // Now I can safely utilize the new state I've created to call other funcs...
     );
 }

Мой взять

Я восхищаюсь простотой и легким весом опции № 2 выше: распространение объекта. Он не требует полифиллирования или отдельной библиотеки, я могу объявить обработчик изменений на одной строке, и я могу быть хирургическим о том, что изменилось. ? Работа со вложенными объектами структур? В настоящее время я предпочитаю Потрясающий

Есть другие способы, которыми вы любите обращаться с государством в реакции? Пожалуйста, звоните через комментарии!

Ищете больше на реагировании? ⚛

Я был авторизован несколько курсов React и JavaScript На плютаре ( бесплатная пробная версия ). Мой последний, ” Создание многоразовых реагированных компонентов «Только что опубликовал!?

Дом Кори автор Несколько курсов по JavaScript, React, Clear Code, .NET и многое другое на Pluralsight Отказ Он главный консультант по адресу Reactjsconsulting.com , архитектор программного обеспечения в Vinsolutions, Microsoft MVP и поезда разработчиков программного обеспечения на международном уровне по методике программного обеспечения, такими как интерфейс разработки и чистого кодирования. Твиты CORY о JavaScript и Front-End Development в Twitter, как @houseCor Отказ

Оригинал: “https://www.freecodecamp.org/news/handling-state-in-react-four-immutable-approaches-to-consider-d1f5c00249d5/”