更新数组变量的状态

时间:2021-06-29 12:21:37

标签: reactjs

我想改变 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;

2 个答案:

答案 0 :(得分:2)

澄清一下,console.log(array); 记录 old 数组的原因不是,因为 setArray(或者更确切地说,它的实现)是或者是不是异步的。这是因为,简单地说,这是不可能。 即使它是完全同步的,它仍然会如此。


原因:

  1. Javascript 是一个 pass-by-value(或者更确切地说是共享调用),或更重要的是不是传递-参考语言。这意味着,绝对没有办法以可以改变分配给 setArray 的方式来实现 array。你甚至不应该假设这是可能的一个死赠品是 array 是一个 const

  2. 除了抛出异常之外,不可能阻止剩余代码after setArray(array => [...array,obj]) from inside setArray的执行.

另请注意,这不是反应式。它只是语言的一部分。所以也没有办法修复这个(不是我说需要修复)。


那么到底发生了什么?不简单:

const submit = (event) => { ... } 在常量 array 上形成一个 closure。因此 console.log(array); 必须引用该值。 setArray(array => [...array,obj]) 暂存下一个渲染的状态更新,以及该过程是同步还是异步,在这里完全无关。


那么如何引用一个改变的状态变量?

  1. 适当地使用 useEffect

  2. 使用您想要分配的值作为计算它的新状态。例如:

    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 调用的同步操作,并且可能会批量调用以提高性能。