Почему дочерний компонент не рендерится заново, хотя родительское состояние обновляется с помощью хуков - PullRequest
1 голос
/ 02 мая 2020

Я новичок ie в React, и у меня возникла проблема с использованием хука. Я собираюсь создать базовую c форму как дочерний компонент, но мне интересно, почему элемент ввода в дочерней форме не отображается при изменении его значения.

Вот мой код.

'use strict';

function SearchForm({form, handleSearchFormChange}) {

    return (
        <div className="card border-0 bg-transparent">
            <div className="card-body p-0 pt-1">
                <div className="form-row">
                    <div className="col-auto">
                        <label className="mr-1" htmlFor="number">Number:</label>
                        <input type="text" className="form-control form-control-sm w-auto d-inline-block"
                               name="number" id="number" value={form.number} onChange={handleSearchFormChange}/>
                    </div>
                </div>
            </div>
        </div>
    );
}

function App() {
    const formDefault = {
        number: 'Initial Value'
    };
    const [form, setForm] = React.useState(formDefault);

    const handleSearchFormChange = (e) => {
        setForm(Object.assign(form, {[e.target.name]: e.target.value}));
        console.log('Handle Search Form Change', e.target.name, "=", e.target.value);
    };

    return (
        <React.Fragment>
            <div>Number : {form.number}</div>
            <SearchForm form={form} handleSearchFormChange={handleSearchFormChange} />
        </React.Fragment>
    );
}

const domContainer = document.querySelector('#root');
ReactDOM.render((
    <React.Fragment>
        <App/>
    </React.Fragment>
), domContainer);

Я определил обработчик события onChange для элемента 'number' в родительском компоненте и попытался передать значение в дочерний компонент с помощью props.

Проблема заключается в том, что когда я собираюсь изменить элемент ввода «номер», «номер» вообще не изменяется. (Не отображается вообще). Так что этот элемент ввода всегда имеет «Начальное значение». Не могли бы вы посоветовать это?

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

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

Одна из философий реакции состоит в том, что государство неизменно. Ie, вы не изменяете свойства существующего объекта состояния, а вместо этого создаете новый объект состояния. Это позволяет реагировать, чтобы сказать, что состояние изменилось простой проверкой === до и после.

Эта строка кода изменяет существующий объект формы, а затем передает его в setForm:

setForm(Object.assign(form, {[e.target.name]: e.target.value}));

Таким образом, реакция сравнивает объект до setForm и после, и видит, что они тот же объект. Поэтому делается вывод, что ничего не изменилось, и поэтому компонент не рендерится.

Вместо этого вам нужно сделать копию объекта и внести изменения в копию. Если вы привыкли к Object.assign, это может быть достигнуто путем помещения пустого объекта в качестве первого аргумента Object.assign:

setForm(Object.assign({}, form, {[e.target.name]: e.target.value}));

В качестве альтернативы, синтаксис распространения является удобным способом сделать поверхностный копия объекта:

setForm({
  ...form,
  [e.target.name]: e.target.value
})
1 голос
/ 02 мая 2020

Попробуйте заменить setForm(Object.assign(form, {[e.target.name]: e.target.value})); на

setForm(prevState => ({
    ...prevstate,
    [e.target.name]: e.target.value
}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...