Я просто хочу сказать, что вам не нужно использовать компонент более высокого порядка, однако, то, что вы пытаетесь сделать, может работать.
Я вижу пару проблем.
Сначала вы устанавливаете InputText
value
в соответствии с состоянием FormLogin
. Это нормально, однако, когда InputText
изменяется, он вызывает onInputChange
, который установлен в setStateFormData
из старшего компонента. Проблема в том, что setStateFormData
устанавливает состояние для компонента высшего порядка, а не состояние для FormLogin
. В результате состояние FormLogin
не обновляется, что означает, что value
для InputText
не обновляется.
Я знаю, что вы думаете: «Но ввод обновляется, прежде чем я нажимаю« Отправить ». Да, и нет.
Это подводит нас ко второй проблеме, связанной с ссылками на JS.
Из документов React
state
- это ссылка на состояние компонента во время применения изменения. Это не должно быть напрямую видоизменено. Вместо этого изменения должны быть представлены путем создания нового объекта на основе ввода от state
и props
.
Если мы посмотрим на setStateFormData
, вы технически непосредственно мутируете state
, сначала ссылаясь на объект в state
с помощью let tempData = state.formdata;
, затем изменяя ссылочный объект с помощью tempData[field] = value;
. Это большая проблема в React, потому что она приводит к всевозможным сбивающим с толку ошибкам, таким как эта.
Вы можете построить новое состояние из старого состояния, но вам разрешено копировать только значения, а не ссылки. Мы можем исправить это, переписав setStateFormData
следующим образом:
setStateFormData(field, value){
this.setState(function(state, props){
let newFormData = {
email: state.formdata.email;
password: state.formdate.password;
};
newFormData[field] = value;
return {
formdata: newFormData
};
});
}
Теперь мы копируем formdata
из старого состояния. Отлично, одна ошибка. Если мы протестируем приложение еще раз, теперь мы видим, что входные данные никогда не обновляются ни до, ни после отправки. Это из-за первой проблемы, упомянутой выше.
Раньше InputText
value
, казалось, обновлялся, потому что состояние FormLogin
, казалось, обновлялось, однако, state.formdata
в FormLogin
было просто ссылкой на state.formdata
в компоненте высшего порядка, который был установлен в конструкторе FormLogin
с formdata: this.props.formdata
. Это означало, что когда setStateFormData
непосредственно мутировал состояние компонента более высокого порядка, он также непосредственно отключал состояние FormLogin
. Это выглядело так, как будто все работало, но на самом деле это было просто из-за ссылок. Как только ссылка потеряна, приложение сломалось. Итак, когда мы потеряли ссылку? Как вы уже догадались, когда мы звоним setState
в handleSubmit
.
self.setState({
alertstatus: 'danger',
alertmessage: 'Login failed. Email or password is incorrect.',
formdata: { email: '', password: '' }
});
Это присвоило state.formdata
в FormLogin
новому объекту, прервав ссылку на state.formdata
в компоненте высшего порядка.
Хорошо, так как это исправить. Есть несколько способов.
Я бы рекомендовал полностью удалить formdata
из состояния FormLogin
. Таким образом, вам не нужно беспокоиться о синхронизации двух formdata
объектов. Просто создайте функцию clearFormData
для компонента высшего порядка и передайте ее в FormLogin
для вызова handleSubmit
. Кроме того, вам нужно установить TextInput
value
в соответствии с реквизитами FormLogin
. Я думаю, что это самое чистое решение, но при этом используется компонент высшего порядка.
Самое простое решение - это, конечно, просто избавиться от компонента более высокого порядка, но я не уверен, если это вариант, если ваша цель специально узнать о компонентах высшего порядка.
Наконец, вы можете реализовать функцию getDerivedStateFromProps для FormLogin
, которая будет перестраивать состояние FormLogin
каждый раз, когда изменяется его реквизит, что по совпадению происходит каждый раз, когда изменяется состояние высшего порядка. Это чистый способ обновления formdata
в FormLogin
каждый раз, когда он изменяется в компоненте высшего порядка. Проблема в том, что вам все еще нужно беспокоиться об обновлении formdata
в компоненте высшего порядка каждый раз, когда он изменяется в FormLogin
.
Надеюсь, это поможет.