晚上好,伙计们,我面临着一个看似简单的问题,对不起我的英语不好。 单击保存按钮时将调用handleSubmit方法,因此三元条件语句检查字段是否在验证中,如果不是,则将其状态更改为true,从而在输入中呈现错误。
初始状态
nameError: false,
cpfError: false,
emailError: false,
phoneError: false,
birthdayError: false,
addressError: false,
numberError: false,
districtError: false,
stateError: false,
cityError: false,
cepError: false,
完整方法提交:
handleSubmit = () => {
this.state.name.length < 4
? this.setState({ nameError: true })
: this.setState({ nameError: false })
this.state.cpf.length < 14
? this.setState({ cpfError: true })
: this.setState({ cpfError: false })
this.state.email.length === 0
? this.setState({ emailError: true })
: this.setState({ emailError: false })
this.state.phone.length < 15
? this.setState({ phoneError: true })
: this.setState({ phoneError: false })
this.state.birthday.length < 10
? this.setState({ birthdayError: true })
: this.setState({ birthdayError: false })
this.state.address.length === 0
? this.setState({ addressError: true })
: this.setState({ addressError: false })
this.state.number.length === 0
? this.setState({ numberError: true })
: this.setState({ numberError: false })
this.state.district.length === 0
? this.setState({ districtError: true })
: this.setState({ districtError: false })
this.state.state.length === 0
? this.setState({ stateError: true })
: this.setState({ stateError: false })
this.state.city.length === 0
? this.setState({ cityError: true })
: this.setState({ cityError: false })
this.state.cep.length !== 9
? this.setState({ cepError: true })
: this.setState({ cepError: false })
if (
!this.state.nameError &&
!this.state.cpfError &&
!this.state.emailError &&
!this.state.phoneError &&
!this.state.birthdayError &&
!this.state.addressError &&
!this.state.numberError &&
!this.state.districtError &&
!this.state.stateError &&
!this.state.cityError &&
!this.state.cepError
) {
this.props.updateUser({
name: this.state.name,
cpf: this.state.cpf,
email: this.state.email,
phone: this.state.phone,
birthday: this.state.birthday,
address: this.state.address,
number: this.state.number,
district: this.state.district,
complement: this.state.complement,
state: this.state.state,
city: this.state.city,
cep: this.state.cep,
avatar: this.state.avatar,
})
}
}
问题在此处的此处。
在此情况下,条件不会显示先前设置的新状态,如果再次单击“保存”按钮,它将显示新状态。我要去哪里错了?有人可以分享知识。在所有字段都为空的情况下,这种情况很快就会在三元条件中每个人的错误状态都变为true,但是if的状态仍然是旧的,这是因为setstate和异步吗?
if (
!this.state.nameError &&
!this.state.cpfError &&
!this.state.emailError &&
!this.state.phoneError &&
!this.state.birthdayError &&
!this.state.addressError &&
!this.state.numberError &&
!this.state.districtError &&
!this.state.stateError &&
!this.state.cityError &&
!this.state.cepError
) {
this.props.updateUser({
name: this.state.name,
cpf: this.state.cpf,
email: this.state.email,
phone: this.state.phone,
birthday: this.state.birthday,
address: this.state.address,
number: this.state.number,
district: this.state.district,
complement: this.state.complement,
state: this.state.state,
city: this.state.city,
cep: this.state.cep,
avatar: this.state.avatar,
})
}
答案 0 :(得分:1)
是的,您使用this.setState()
和this.props.updateUser()
创建的逻辑是异步的。您想要的是在更新状态后呼叫this.props.updateUser()
。 this.setState()
实际上带有一个可选的辅助参数,您可以在状态完成更新后调用它,这正是您所需要的。
让我在这里通过帮助您重组一些代码来帮助您。这也是沙盒:https://codesandbox.io/s/zxpnk301pl
此外,您真的要避免在每次检查输入值时不断更新状态。这可能会导致非常糟糕的性能问题。最好仅执行一项操作即可更新状态。
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
state = {
name: '',
cpfr: '',
email: '',
phone: '',
birthday: '',
address: '',
number: '',
district: '',
state: '',
city: '',
cep: '',
errors: {},
}
handleOnChange = event => {
this.setState({
[event.target.name]: event.target.value,
})
}
validateAndSubmit = event => {
event.preventDefault()
const {
name,
cpfr,
email,
phone,
birthday,
address,
number,
district,
state,
city,
cep,
errors,
} = this.state
name.length < 4 ? (errors.name = true) : delete errors.name
cpfr.length < 14 ? (errors.cpfr = true) : delete errors.cpfr
email.length === 0 ? (errors.email = true) : delete errors.email
phone.length < 15 ? (errors.phone = true) : delete errors.phone
birthday.length < 10 ? (errors.birthday = true) : delete errors.birthday
address.length === 0 ? (errors.address = true) : delete errors.address
number.length === 0 ? (errors.number = true) : delete errors.number
district.length === 0 ? (errors.district = true): delete errors.district
state.length === 0 ? (errors.state = true) : delete errors.state
city.length === 0 ? (errors.city = true) : delete errors.city
cep.length !== 9 ? (errors.cep = true) : delete errors.cep
this.setState(
{
errors: errors,
},
() => {
//check if there are no errors
if(Object.keys(this.state.errors).length === 0){
this.props.updateUser({
name: this.state.name,
cpf: this.state.cpf,
email: this.state.email,
phone: this.state.phone,
birthday: this.state.birthday,
address: this.state.address,
number: this.state.number,
district: this.state.district,
complement: this.state.complement,
state: this.state.state,
city: this.state.city,
cep: this.state.cep,
avatar: this.state.avatar,
})
}
}
)
}
render() {
return (
<div>
<form onSubmit={this.validateAndSubmit}>
<input
name="name"
value={this.state.name}
onChange={this.handleOnChange}
/>
<input
name="cpfr"
value={this.state.cpfr}
onChange={this.handleOnChange}
/>
<input
name="email"
value={this.state.email}
onChange={this.handleOnChange}
/>
<input
name="phone"
value={this.state.phone}
onChange={this.handleOnChange}
/>
<input
name="birthday"
value={this.state.birthday}
onChange={this.handleOnChange}
/>
<input
name="address"
value={this.state.address}
onChange={this.handleOnChange}
/>
<input
name="number"
value={this.state.number}
onChange={this.handleOnChange}
/>
<input
name="district"
value={this.state.district}
onChange={this.handleOnChange}
/>
<input
name="state"
value={this.state.state}
onChange={this.handleOnChange}
/>
<input
name="city"
value={this.state.city}
onChange={this.handleOnChange}
/>
<input
name="cep"
value={this.state.cep}
onChange={this.handleOnChange}
/>
<button>Submit</button>
</form>
You have {Object.keys(this.state.errors).length} errors
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
答案 1 :(得分:1)
问题在于setState
是异步的,但是您要在状态完成更新之前检查它。您可以将其重构为一个调用,而不是对每个检查进行多个setState
调用,然后在setState
回调中进行更新,例如:
// Collect all of your error items
const nameError = this.state.name.length < 4;
const cpfError = this.state.cpf.length < 14;
...
// Set the state with your error values
this.setState({
nameError,
cpfError,
...
}, () => { // <-- The second parameter of setState is a callback called after it is finished
if (
!this.state.nameError &&
!this.state.cpfError &&
...
) {
this.props.updateUser({
name: this.state.name,
...
});
}
);