【问题标题】:useState referring to stale valueuseState 指的是陈旧的值
【发布时间】:2020-09-27 09:56:38
【问题描述】:

我有一个 keeper 应用程序,我在其中添加笔记并将它们存储在数据库中。当我向服务器发出 post 请求时,我试图从数据库中获取 _id,这最终将帮助我稍后删除注释(如果需要)。 这是我的 jsx 文件

function CreateMessage(props) {   

    const [currentGuest, setCurrentGuest] = useState({
        guestName: '',
        guestMessage: '',
        id:''
    });

    function handleMessages(event) {
        const {name, value} = event.target;
        setCurrentGuest(prevGuest => {
            return {
                ...prevGuest,
                [name] : value
            };
        });
    }


    function submitMessage(event) {
    //props.onAdd(currentGuest);
    const params = {
      guestName: currentGuest.guestName,
      guestMessage: currentGuest.guestMessage,
    }
    axios
    .post("http://localhost:8000/notes", params)
    .then(res => {
      console.log("The response is"+res.data._id);
      console.log(res.status);
      setCurrentGuest(prevGuest => {
        console.log(res.data._id)
            return {
                ...prevGuest,
                id: res.data._id
            };
        });
        console.log(currentGuest);
    })

    event.preventDefault();
    }

    return (
    <div>
      <form>
        <input
          name="guestName"
          placeholder="Guest Name"
          value={currentGuest.guestName}
          onChange={handleMessages}
        />
        <textarea
          name="guestMessage"
          placeholder="Write a Message"
          rows="3"
          value={currentGuest.guestMessage}
          onChange={handleMessages}
        />
        <button onClick={submitMessage}>Add</button>
      </form>
    </div>
  );

}

id 被正确地获取并显示在 ```console.log("The response is"+res.data._id") 中。但是在第一次提交时,总是空的并且陈旧的 id 被附加到 currentGuest下次提交对象

【问题讨论】:

  • 代码看起来像是在.then() 中将函数传递给 setCurrentGuest,这是故意的吗?
  • 是的,我正在尝试从响应中获取 id 并使用它在 setCurrentGuest 中的 currentGuest 对象中设置 id
  • 不应该 setCurrentGuest 获取对象吗?
  • @DonaldP - setStateuseState 也可以以函数方式使用。当新状态依赖于旧状态时,我们会这样做。
  • 啊,我今天学到了新东西,谢谢!

标签: reactjs axios use-state


【解决方案1】:
function submitMessage(event) {
//props.onAdd(currentGuest);
const params = {
  guestName: currentGuest.guestName,
  guestMessage: currentGuest.guestMessage,
}
axios
.post("http://localhost:8000/notes", params)
.then(res => {
  console.log("The response is"+res.data._id);
  console.log(res.status);
  setCurrentGuest(prevGuest => {
    console.log(res.data._id)
        return {
            ...prevGuest,
            id: res.data._id
        };
    });
    console.log(currentGuest);
})

event.preventDefault();
}

在上面的 sn-p 中,在获得响应后,您正确地更改了状态,但问题在于您检查更改状态的位置(console.log(currentGuest))。您基本上是在状态更改之前进行记录。

您可以使用useEffect 挂钩并记录其中的状态。每次currentGuest 更改时都会运行。

useEffect(() => {
 console.log(currentGuest)
}, [currentGuest])

更新

你可以在useEffect钩子里面使用修改后的currentGuest

useEffect(() => {
  console.log(currentGuest)
  if(currentGuest.id) {
   props.onAdd(currentGuest);
   // You can also reset the state here as follows
   setCurrentGuest({
    guestName: '',
    guestMessage: '',
    id:''
   });
  }
}, [currentGuest]) // You might need to add the necessary dependencies to this array.

【讨论】:

  • 谢谢@Ramesh。它确实给了我更新的价值,但就像你说的那样。但我实际上打算在 currentGuest 对象中更新正确的 id 时调用注释方法 props.onAdd(currentGuest),然后最后将 currentGuest 对象再次设置为空。但如果我这样放置:setCurrentGuest(prevGuest =&gt; { return { ...prevGuest, id: res.data._id }}); props.onAdd(currentGuest);} 它甚至在 id 更新之前再次被调用。我们有办法管理它吗?我应该设置一些超时时间吗?
  • 基本上,如果我不想控制对象值,但当我在对象中有更新的 id 时还运行几行代码怎么办?这种代码应该放在哪里
  • @NoopurPorwal - 这正是你应该使用useEffect 钩子的时候。请参阅我的更新答案。
猜你喜欢
  • 1970-01-01
  • 2020-03-01
  • 2015-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 2014-11-22
相关资源
最近更新 更多