挂钩未在REACT中设置状态

时间:2019-12-22 12:52:02

标签: reactjs react-native jasmine react-hooks

在以下代码中,下面显示的钩子不会更改变量newName的状态。

import React, { useState } from 'react'

const App = () => {
    const [ persons, setPersons] = useState([
        { name: 'Arto Hellas' }
    ])
    const [ newName, setNewName ] = useState('')

    const textChangeHandler = (event)=>{
        event.preventDefault()
        setNewName(event.target.value) // WORKS FINE
    }

    const submitHandler = (event)=>{
        event.preventDefault()

        let temp = {name:newName}
        setNewName('')    //////////////////////////////////////// PROBLEM - doesnot set state!!
        console.log('tenp name is',temp.name)
        console.log('new name is',newName)
        setInterval(()=>console.log("Set Interval",newName), 1000)
    }

    return (
        <div>
            <h2>Phonebook</h2>
            <form onSubmit={submitHandler}>
                <div>
                    name: <input onChange={textChangeHandler}  />
                </div>
                <div>
                    <button type="submit" >add</button>
                </div>
            </form>
            <h2>Numbers</h2>
            {persons.map((person) => <Person key = {person.name} name={person.name}/> )}
        </div>
    )
}

const Person  = ({name})=> <p> {name} </p>

setNewName可以正常工作,并且在输入框中键入任何内容时,名称都会更新。但是,当我提交按钮时,setNewName似乎不起作用。即使更新后,执行setNewName的名称仍然是旧名称。 我什至尝试了setInterval(认为它可能是由于JS的异步特性引起的)并打印了newName,但是它仍然显示旧名称。

问题出在哪里,如何解决?

谢谢

3 个答案:

答案 0 :(得分:0)

如果您查看自己的submitHandler函数,您会发现其自身名称未更改……在初始状态下它保持为空。仅当状态值更改如下所示时,React才会重新加载

const submitHandler = (event)=>{
        event.preventDefault()

        let temp = {name:newName}
        //setNewName('')    // your value is not changing here ... removing line
        setNewName(temp.name) // changing the name here with the one in temp
        console.log('tenp name is',temp.name)
        console.log('new name is',newName)
        setInterval(()=>console.log("Set Interval",newName), 1000)
    }

答案 1 :(得分:0)

您知道设置状态是异步的。 切勿使用setTimeout setInterval之类的调度功能注销状态值。

改为使用useEffect-

  useEffect(() => {
    console.log("value is", newName);
  }, [newName]);

您的钩子工作正常,没有问题。这是codeSandbox,显示一切正常。

答案 2 :(得分:0)

在React中setState不是同步的(带有类组件和钩子)。 因此,您不能期望一个新状态将立即可用。 您需要更改submitHandler函数的实现。