【问题标题】:React useRef hook: useRef value not be used by a useState function反应 useRef 钩子:useRef 值不被 useState 函数使用
【发布时间】:2021-04-01 10:49:26
【问题描述】:

在我问这个问题之前,我自然地搜索了一下,发现了这个great post

在我解释一下序言之后,我将在稍后展示我的实现。

基本上我的问题是 useState 中的更新程序函数没有同步更新,它在它获取的数据中落后了。

useState 函数传递一个对象,该对象包含 id、lat 和 lang。

currentCoords: [{id: 1, lat: 40.74003514370453, lng: -73.76452126968704}]
markers: [{id: 0, lat: 40.74168820148129, lng: -73.76539693565009},…]
0: {id: 0, lat: 40.74168820148129, lng: -73.76539693565009}
1: {id: 1, lat: 40.74003514370453, lng: -73.76452126968704}

currentCoords,应该镜像标记数组。如您所见,它是“设置”第二个。

所以我都知道,因为 setState 和 useState 是异步的,你不能依赖正在更新的状态。

现在这是我尝试过的:

 useEffect(() => {
    if (userMarkers.length === 1) {
      userMarkersRef.current = userMarkers[0]; // {id: 0, lat: 40.74168820148129, lng: -73.76539693565009}
      setUserCoords(userMarkersRef.current);

      setIsRoutingVisibileFalse();
    }
    if (userMarkers.length === 2) {
      userMarkersRef.current = userMarkers[1]; // {id: 1, lat: 40.74003514370453, lng: -73.76452126968704}
      setUserCoords(userMarkersRef.current);
    }
  }, [JSON.stringify(userMarkers)]);

我在 useEffect 依赖项中包含了一个数组,该数组已被字符串化,以便在它 (useMarkers) 更改时启动(不用担心数组永远不会超过两个项目!)

我想通过保存一个显式引用,然后将它传递给可以工作的更新程序,但它没有:(

这是 setState 函数,将其保存到本地存储:

  setUserCoords: coords => {
   setUser({
     ...user,
     currentCoords: [{ ...user.currentCoords[coords.id], ...coords }]
   });
  },

【问题讨论】:

  • userMarkers 是从哪里来的?
  • 您好!它也是存储在本地存储中的用户对象上的一个数组。

标签: javascript reactjs use-state use-ref


【解决方案1】:

基本上我的问题是 useState 中的更新函数不是 同步更新,它获得的数据落后了。

看起来通过setUser 内部的闭包引用的user 是陈旧的。

由于您的下一个状态取决于您之前的状态,您可以使用其他形式的setState 来获取之前状态的最新快照。

即-

setUserCoords: coords => {
   setUser((prevState) => {
     return {
       ...prevState.user,
       currentCoords: [{ ...prevState.user.currentCoords[coords.id], ...coords }]
     }
   });
  },

来自React docs

updater 函数接收到的 state 和 props 都是有保证的 是最新的。更新器的输出与 状态。

【讨论】:

  • 感谢您的回复!我尝试了你的解决方案,我得到了TypeError: Cannot read property "currentCoords" of undefined `
  • 完整的state 看起来像setUser 正在设置什么?
  • 抱歉耽搁了...var initialState = { avatar: '/static/uploads/profile-avatars/placeholder.jpg', isRoutingVisibile: false, removeRoutingMachine: false, markers: [], currentMap: {}, currentCoords: [] };
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2019-10-20
  • 2020-07-10
  • 2022-10-12
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多