我是新来的反应,所以请耐心等待。我正在使用登录表单,此表单将在提交表单后实时验证并且错误成为现实。无论如何,默认情况下我有状态isFormValid: false
的属性。
这将通过handleFormSubmission构造函数更新:
/**
* handleFormSubmission, submission method for user
* account login. Dispatches the login action.
*
* @param {Object} event
*/
handleFormSubmission(event) {
event.preventDefault();
this.setState({
formSubmitted: true
},() => {
this.validateForm();
if (this.state.isFormValid) {
if (this.state.userCreatingAccount) {
this.props.createUserAccount(
this.state.email,
this.state.password,
this.state.firstName,
this.state.lastName
)
} else {
this.props.login(
this.state.email,
this.state.password
);
}
}
});
}
我在我的状态对象中设置formSubmitted: true
,然后通过回调执行表单提交。我的问题是this.validateForm()
。在setState
内部this.validateForm()
完成后,我需要执行代码。也许我可以宣传它? this.validateForm().then(functio.......)
。这样做有问题,因为这个函数不只是一次更新状态,而是动态多次。
这是我的验证表单功能:
/**
* function validateForm, error handling for
* dynamic form input fields. Resets state errors
* on exection, then updates state via callback.
*/
validateForm(){
// Reset state.
this.setState({
isFormValid: true,
errors: Object.assign(this.state.errors, {
email: {},
password: {},
firstName: {},
lastName: {}
})
}, () => {
if (this.state.formSubmitted) {
// Iterate over input fields, if length is 0
// set an error via the state name.
for (var inputField in this.state.errors) {
if (this.state.errors.hasOwnProperty(inputField)) {
if (inputField !== 'email') {
if (
!this.state.userCreatingAccount &&
inputField !== 'firstName' &&
inputField !== 'lastName'
) {
if (this.state[inputField].length === 0) {
this.setState({
isFormValid: false,
errors: Object.assign(this.state.errors, {
[inputField]: {
required: true
}
})
});
}
} else {
if (this.state[inputField].length === 0) {
this.setState({
isFormValid: false,
errors: Object.assign(this.state.errors, {
[inputField]: {
required: true
}
})
});
}
}
} else {
// Email validation.
if (this.state[inputField].length === 0) {
this.setState({
isFormValid: false,
errors: Object.assign(this.state.errors, {
[inputField]: {
required: true
}
})
});
} else if (!/^((?!.*\.\.)[a-z0-9\.\-]+[^\.]@[a-z0-9\-]+(?:\.[a-z]+)+)$/mgi.test(
this.state[inputField]
)) {
this.setState({
isFormValid: false,
errors: Object.assign(this.state.errors, {
[inputField]: {
invalid: true
}
})
});
}
}
}
}
}
});
}
简而言之,此函数更新输入字段的状态。它动态地执行,意味着1,2,3,4等字段,具体取决于那些字段值。我希望this.validateForm()内部的逻辑首先完成。紧随其后的代码取决于在this.validateForm()中设置的新状态值。但是setState是异步的。
希望这个问题有道理!提前谢谢。
答案 0 :(得分:2)
你的代码对我来说有点太复杂,无法提供一个有效的例子,但我想我可以给你一些你可以做的事情。
我看到的第一个问题是你有办法,太多了setState()
。这本身并不坏,但管理复杂的逻辑是一个令人头疼的问题。很容易意外地出现多次重新渲染的情况,这些都是徒劳的。
这就是我要做的事情:
分解与UI的表示没有直接关系的任何状态变量。例如,似乎就像您的formSubmitted
变量仅用于您的逻辑中以确定if...else
结果。
您可能需要仔细检查这一点,但如果是这种情况,请将此类变量放在组件实例中。与this.formSubmitted
代替this.state.formSubmitted
一样。为什么这样?它简化了您的应用程序逻辑,使您无需执行异步setState
,然后在回调中继续您的逻辑...
请勿在{{1}}中进行任何状态更改。而是构造一个新对象,它反映了下一个渲染中所需状态的对象。在函数结束时,返回此构造对象。
您现在可以在validateForm()
函数中设置状态为handleFormSubmission()
,其中this.setState(obj)
是您从上面的步骤2返回的对象。在obj
的回调中做最后一点逻辑。如果您返回的对象包含所有需要的变量(我没有检查),您甚至可以跳过回调,只需检查setState()
而不是obj
。
TL; DR 努力在应用中的任何一个操作或流程中始终执行单this.state
。这并非总是可行,但应该在99.999%的时间内完成。
答案 1 :(得分:1)
我认为您可以使用React组件生命周期。我喜欢这篇关于解释的文章:http://busypeoples.github.io/post/react-component-lifecycle/,或者你可以从这里阅读有关setState的内容:https://reactjs.org/docs/react-component.html#setstate。
我们可以使用componentDidUpdate()
在组件状态更改后执行操作。这是对代码的修改:
componentDidUpdate() {
if (this.state.isFormValid) {
if (this.state.userCreatingAccount) {
this.props.createUserAccount(
this.state.email,
this.state.password,
this.state.firstName,
this.state.lastName
)
} else {
this.props.login(
this.state.email,
this.state.password
);
}
}
handleFormSubmission(event) {
event.preventDefault();
this.setState({
formSubmitted: true
},() => {
this.validateForm();
/* move them to componentDidUpdate() */
//if (this.state.isFormValid) {
// if (this.state.userCreatingAccount) {
// this.props.createUserAccount(
// this.state.email,
// this.state.password,
// this.state.firstName,
// this.state.lastName
// )
// } else {
// this.props.login(
// this.state.email,
// this.state.password
// );
// }
}
});
}
希望这可以提供帮助。