我有以下代码:
import React,{useState} from 'react'
const iState ={
Name : '',
Email :'',
Salary :0,
Error:{
EName:'*',
EEmail:'*',
ESalary:'*'
}
}
function ReactForm() {
const [state, setstate] = useState(iState);
function validationHandler(e)
{
switch (e.target.name) {
case 'txtName':
console.log(e.target.value);
if(e.target.value=='')
{
console.log('inside condition')
setstate({...state.Error, EName:'Value Cannot be blank'})
console.log(state);
}
else
{
console.log('inside else condition')
setstate({...state, EName:''})
}
setstate({...state, Name:e.target.value})
break;
case 'txtEmail':
setstate({...state, Email:e.target.value})
break;
case 'txtSalary':
setstate({...state, Salary:e.target.value})
break;
default:
break;
}
console.log(state);
}
return (
<div>
Name : <input name="txtName" type="text" onChange={(e)=>validationHandler(e)}></input>
<label> {state.Error.EName==undefined ? '*':state.Error.EName} </label>
<br></br>
Email : <input name="txtEmail" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
Salary : <input name="txtSalary" type="text" onChange={(e)=>validationHandler(e)}></input>
<br></br>
<button onClick={validationHandler}>Validate Us</button>
</div>
)
}
export default ReactForm
在这里,iState 中嵌套了 Error 部分 -
const iState ={
Name : '',
Email :'',
Salary :0,
Error:{
EName:'*',
EEmail:'*',
ESalary:'*'
}
}
当我尝试更新 Error 的嵌套状态时,它没有得到更新 -
if(e.target.value=='')
{
console.log('inside condition')
setstate({...state.Error, EName:'Value Cannot be blank'})
console.log(state);
}
else
{
console.log('inside else condition')
setstate({...state, EName:''})
}
我可以看到它进入 else 块,但没有更新状态。
我也试过 - setstate({...state.Error, EName:''})
编辑 1:
if(e.target.value=='')
{
console.log('inside condition')
setstate({ ...state, Error: { ...state.Error, Ename: 'Value Cannot be blank' }})
console.log(state);
}
else
{
console.log('inside else condition')
setstate({ ...state, Error: { ...state.Error, Ename: 'Value Cannot be blank' }})
}
设置状态已更改 -setstate({ ...state, Error: { ...state.Error, Ename: 'Value Cannot be blank' }})
仍然没有更新 -
答案 0 :(得分:2)
您不应在设置新状态时直接使用之前的状态,因为状态更改是异步的。
setState((prevState)=>{...prevState, Error: { ...prevState.Error, EName:'Value Cannot be blank' }})
答案 1 :(得分:1)
你应该这样做
setstate({...state, Error: { ...state.Error, EName:'Value Cannot be blank' }})
答案 2 :(得分:1)
您必须使用传播当前状态并更新嵌套的 vaues
setState( previous => {...previous, Error: { ...previous.Error, EName:'Value Cannot be blank'} })
答案 3 :(得分:1)
与类组件中的 this.setState
不同,useState
钩子返回的状态 setter 函数不会将旧状态与新状态合并 - 您需要自己完成。不这样做将覆盖现有状态。
目前您正在覆盖现有状态。更新状态的正确方法如下所示:
这个
setstate({...state.Error, EName:'Value Cannot be blank'})
应该
setstate({ ...state, Error: { ...state.Error, Ename: 'Value Cannot be blank' } })
解释为什么会这样:
首先,您在传递给 setState
的新创建的对象中传播顶级状态对象。之后,您添加 Error
键,其值是另一个对象,您可以在其中扩展 state.Error
。最后,在嵌套对象中添加 Ename
键并设置其值。
以上步骤重新创建了一个与初始状态对象结构相似的新对象。
同样如此
setstate({...state, EName:''})
应该
setstate({...state, Error: { ...state.Error, EName:'' } })
请注意,状态是异步更新的,并且在组件的特定渲染中保持不变。
这意味着在调用状态设置器函数后立即记录状态将记录旧状态。组件只能看到更新的状态在它重新渲染之后。
要记录更新的状态,请使用 useEffect
钩子,如下所示:
useEffect(() => {
console.log(state);
}, [state]);
这将记录更新的状态,因为它将执行:
state
更新而重新渲染组件。