我想改变 setArray 的状态,但我不能改变它。 console.log 显示空数组。其他州正在工作,但不是这个 我也使用过 useEffect 但什么也没发生。请给我一个解决方案。
import React from 'react';
import { Link} from 'react-router-dom'
import {useEffect} from 'react';
const Register = () =>{
const classes = useStyle();
const [name, setName] = React.useState('');
const [password, setPassword] = React.useState('');
const [array, setArray] = React.useState([])
const submit = (event) =>{
const obj = {}
event.preventDefault();
if(array.length === 0){
localStorage.setItem('name', name);
localStorage.setItem('password',password);
localStorage.setItem('array',JSON.stringify(array))
obj.id = Math.random();
obj.name = localStorage.getItem('name');
obj.password = localStorage.getItem('password');
setArray(array => [...array,obj])
console.log(array);
return alert('You are registered');
}
}
return(
<div>
<div className = {classes.formWrapper}>
<Paper elevation={3} className = {classes.paper} >
<Typography variant="h5" style = {{ textAlign : 'center'}}>Register</Typography>
<form noValidate autoComplete="off">
<TextField id="username" className={classes.textfield} style={{width : '95%'}} value = {name} name = "username" label="Username" onChange = {e=>setName(e.target.value)} />
<br />
<TextField id="password" className={classes.textfield} style={{width : '95%'}} value = {password} name = "password" label="Password" onChange = {e=>setPassword(e.target.value)} />
<br />
<br />
<Link to='/'>SignIn</Link>
<Button variant="contained" color="secondary" style = {{width : '100%'}} onClick = {submit} >Register </Button>
</form>
</Paper>
</div>
</div>
)
}
export default Register;
答案 0 :(得分:2)
澄清一下,console.log(array);
记录 old 数组的原因不是,因为 setArray
(或者更确切地说,它的实现)是或者是不是异步的。这是因为,简单地说,这是不可能。
即使它是完全同步的,它仍然会如此。
原因:
Javascript 是一个 pass-by-value(或者更确切地说是共享调用),或更重要的是不是传递-参考语言。这意味着,绝对没有办法以可以改变分配给 setArray
的方式来实现 array
。你甚至不应该假设这是可能的一个死赠品是 array
是一个 const
。
除了抛出异常之外,不可能阻止剩余代码after setArray(array => [...array,obj])
from inside setArray
的执行.
另请注意,这不是反应式。它只是语言的一部分。所以也没有办法修复这个(不是我说需要修复)。
那么到底发生了什么?不简单:
const submit = (event) => { ... }
在常量 array
上形成一个 closure。因此 console.log(array);
必须引用该值。 setArray(array => [...array,obj])
暂存下一个渲染的状态更新,以及该过程是同步还是异步,在这里完全无关。
那么如何引用一个改变的状态变量?
适当地使用 useEffect
。
使用您想要分配的值作为计算它的新状态。例如:
setArray(array => {
const next = [...array, obj];
console.log(next); // new value
return next;
});
console.log(array); // *still* the old value, for the above mentioned reasons
答案 1 :(得分:0)
setState 是异步的。这意味着你不能在一行调用它并假设状态在下一行发生了变化。
来自 React 文档。
<块引用>setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。