Reactjs - Почему состояние значения формы обновляется как через родительский реквизит, так и через компонент onChange?

Я читаю книгу Fullstack React, и в своем примере проверки формы они создают свой собственный компонент поля (стр. 204-212), а затем сохраняют значение поля как в состоянии поля, так и в родительском состоянии, что сбивает с толку меня. Их компонент Field имеет свойство value, а также состояние, содержащее value. Родительский компонент должен знать о каждом значении поля, чтобы он мог выполнять проверку формы в целом, и поэтому он также имеет состояние, содержащее value.

Внутри поля они обрабатывают изменения value, устанавливая состояние поля при изменении входного value и используя getDerivedStateFromProps при изменении свойства value:

//(within Field)
getDerivedStateFromProps(nextProps) {
     return {value: nextProps.value}
}

onChange = evt => {
    const name = this.props.name;
    const value = evt.target.value;
    const error = this.props.validate ? this.props.validate(value) : false;

    this.setState({value, error});

    this.props.onChange({name, value, error});
};

Они также синхронизируют состояние значения в другом направлении с родительским, вызывая родительскую функцию onInputChange (переданную как свойство onChange):

//(within parent component)
onInputChange = ({name, value, error}) => {
    const fields = Object.assign({}, this.state.fields);
    const fieldErrors = Object.assign({}, this.state.fieldErrors);

    fields[name] = value;
    fieldErrors[name] = error;

    this.setState({fields, fieldErrors});
};

В книге на самом деле не объясняется, почему они дублируют такое состояние, за исключением того, что говорится:

"There are only two pieces of data that Field will need, the current value and error. Like in previous sections where our form component needed that data for its render() method, so too does our Field component."

а также

"One key difference is that our Field has a parent, and sometimes this parent will want to update the value prop of our Field. To allow this, we’ll need to create a new lifecycle method, getDerivedStateFromProps() to accept the new value and update the state."

Я просто новичок, но, на мой взгляд, было бы разумнее полностью отказаться от состояния value в Field и просто передать его как опору. Когда ввод изменяется, вызовите метод onChange с полем и вызовите родительский onInputChange внутри него. Попросите onInputChange обновить родительское состояние о значении поля и передать значение поля в качестве опоры в поле. То, как это делается сейчас, кажется излишним и более подверженным ошибкам. Любое понимание того, почему они делают это таким образом?

Я полностью согласен с тобой. Они обязательно должны поднять состояние и сохранить единый источник правды.

Jonas Wilms 18.05.2018 17:39

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

MEnf 18.05.2018 17:47

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

josephnvu 18.05.2018 17:51

@JonasW. Спасибо :) Но интересные ребята, думаю, позже посмотрю, есть ли в этом смысл.

ogreenworld 18.05.2018 17:55

@josephnvu Мне пока нравится эта книга, так что, надеюсь, она обретет смысл позже, или это всего лишь один запутанный пример: T

ogreenworld 18.05.2018 17:56

Сохранение локального значения может иметь смысл, если вы обновляете родительское значение только в том случае, если оно действительно. У меня есть проверяющий входной компонент, который делает именно это. Может быть, они работают над чем-то подобным в вашей книге?

Oblosys 18.05.2018 18:00

Я не считаю эту настройку проблематичной. Формы - не ваш типичный компонент; вы часто найдете этот общий шаблон с библиотеками форм, где отдельный компонент поддерживает свое собственное состояние, но затем уведомляет родительский, который, в свою очередь, должен агрегировать состояние отдельных лиц и запускать глобальную проверку.

lux 18.05.2018 18:01

@Oblosys Я сомневаюсь в этом, я думаю, они хотят обновить родительский элемент в любом случае.

ogreenworld 18.05.2018 18:14
Поведение ключевого слова "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) для оценки ваших знаний,...
3
8
345
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Книгу не читал, но здесь я объясню, зачем мне писать такой код.

Главное в наличии двух состояний - сделать компонент Field более универсальным.

В этом конкретном случае родитель также сохраняет значение в своем состоянии, и компонент Field становится управляемым компонентом, обновляя свое состояние из полученного props на getDerivedStateFromProps.

Однако все еще существует возможность использовать компонент Field как неконтролируемый компонент, тогда состояние Field будет единственным источником истины.

В обоих случаях есть только один источник истины, который поддерживает способ действий React, однако компонент Field может использоваться как в контролируемой, так и в неконтролируемой форме.

Ах хорошо. В этом есть большой смысл. Раньше они говорили о преобразовании своих форм ввода из неконтролируемых (с использованием ref) в контролируемые компоненты и о том, что они действительно не рекомендуют неконтролируемые. Но я предполагаю, что они сделали это здесь, чтобы все еще могло работать неконтролируемо.

ogreenworld 18.05.2018 18:23

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