Я мутирую объект?

я мутирую объект состояния

state = {
  selectedHero: { id: "", name: "", saying: "" }
}

с этим методом

handleChangeEvent = e => {
  let selectedHero = this.state.selectedHero;
  selectedHero[e.target.name] = e.target.value;

  this.setState({ selectedHero });
};

я должен написать что-то подобное?

handleChangeEvent = e => {
  let selectedHero = { ...this.state.selectedHero };
  selectedHero[e.target.name] = e.target.value;

  this.setState({ selectedHero });
};

console.info () ..

NiVeR 24.05.2018 19:31

Как говорит AnilRedshift, да, приведенный вами пример синтаксиса распространения будет работать нормально. Для более аккуратного подхода вы также можете написать его одним лайнером, например: this.setState({...this.state.selectedHero, name: e.target.value}). Это одновременно перезапишет значение имени на новом объекте и предотвратит изменение.

TPHughes 24.05.2018 19:38

@TPHughes - Нет, версия Анила не использует обратный вызов, который необходим. Также name! = [e.target.name]. :-)

T.J. Crowder 24.05.2018 19:40

Ах да, ты абсолютно прав. Я неправильно прочитал название ключа как просто name. Пишу на телефон: - /. Что вы имеете в виду, зачем нужен обратный вызов?

TPHughes 24.05.2018 19:42

@TPHughes - См. Мой ответ ниже и ссылку в нем. :-)

T.J. Crowder 24.05.2018 19:42

@TPHughes - LOL, я не вставил ссылку! Есть сейчас. :-)

T.J. Crowder 24.05.2018 19:43

Не имел представления! Спасибо очень информативно. :)

TPHughes 24.05.2018 20:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
7
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, вы изменяете объект selectedHero. Вы должны сделать что-то вроде этого:

handleChangeEvent = e => {
  let selectedHero = Object.assign({}, this.state.selectedHero);
  selectedHero[e.target.name] = e.target.value;
  this.setState({ selectedHero });
};

Вызов Object.assign создаст объект новый, так что исходный объект selectedHero не будет изменен.

Обновлено: ваше отредактированное использование Синтаксис распространения ES2018 тоже работает.

Поскольку это включает в себя настройку состояния на основе существующего состояния (других свойств selectedHero, которые вы копируете), вы должен используете версию обратного вызова setState: reactjs.org/docs/…. объединены / объединены.

T.J. Crowder 24.05.2018 19:37
Ответ принят как подходящий

И да и нет. Вы не мутируете this.state, но вы мутируете объект, на который ссылается this.state. Этого не следует делать в React.

should I write something like this?

Почти; поскольку это включает в себя обновление состояния на основе состояния (другие свойства selectedHero), вы должен использовать версию обратного вызова setState. Поскольку это означает использование свойств из синтетического события после возврата handleChangeEvent, нам нужно получить их заранее:

handleChangeEvent = e => {
  const {name, value } = e.target;
  this.setState(prevState => {
    let selectedHero = { ...prevState.selectedHero };
    selectedHero[name] = value;
    return { selectedHero };
  })
};

Если вы не используете версию обратного вызова, будет казаться, что большую часть времени что-то работает, и не удастся, когда у вас есть перекрывающиеся обновления состояния для selectedHero (помните, что обновления состояния являются асинхронными); один будет топтать другого.


Если хотите, вы также можете сжать его, используя вычисленное имя свойства после распространения свойства:

handleChangeEvent = e => {
  const {name, value} = e.target;
  this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};

и даже добавить деструктурирование некоторых параметров:

handleChangeEvent = ({target: {name, value}}) => {
  this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};

(Да, деструктуризация произойдет до возврата handleChangeEvent. Это произойдет до того, как ваш явный код в handleChangeEvent вообще запустится.)

Я получаю предупреждение: это синтетическое событие повторно используется по соображениям производительности. Если вы видите это, вы обращаетесь к свойству target в синтетическом событии выпущено / аннулировано. Для него установлено значение null. Если вы должны сохранить исходное синтетическое событие, используйте event.persist ()

d_oram 24.05.2018 19:56

@d_oram - Ого, я не знал об этом. Тем не менее, приятное четкое сообщение об ошибке. Придется получить name и value локально, а затем использовать их. Вы, наверное, знаете, как это сделать, но я все равно обновлю ответ.

T.J. Crowder 24.05.2018 19:57

@d_oram - Готово.

T.J. Crowder 24.05.2018 19:59

отлично спасибо. Не могли бы вы добавить закрывающую скобку }) после return { selectedHero } в первом примере

d_oram 24.05.2018 20:18

@d_oram - Ой! Во втором и третьем также отсутствовал }. :-)

T.J. Crowder 25.05.2018 08:06

Другие вопросы по теме