更新时反应钩子状态未定义

Posted

技术标签:

【中文标题】更新时反应钩子状态未定义【英文标题】:React hooks state is undefined when updating 【发布时间】:2020-09-24 23:37:31 【问题描述】:

我有一个简单的 React Hooks 组件。当我尝试使用 setLightState 函数更新 lightState 时,它​​会为当前状态返回 undefined。访问返回体内的状态可以正常工作。

const MainControl = () => 
  const [lightState, setLightState] = useState()
  const [lightChan, setLightChan] = useState()

  const updateLight = (newState) => 
    setLightState(...lightState, ...newState)
  

  useEffect(() => 

    socket.connect()
    let chan = socket.channel("lights:dioder")

    chan.join().receive("ok", (response) => 
      setLightState(response)
      setLightChan(chan)
    )

    chan.on("light_colour", (resp) => 
      updateLight(resp)
    )

    return () => 
      chan.leave()
    
  , [])

  if (!lightChan) return <h2>Loading...</h2>

  return (
     <h2>Lights are currently lightState.on ? "on" : "off"</h2>
  )


updateLight 函数将lightState 读取为undefined,但返回主体不是?我认为这可能只在第一次渲染时才成立,但我不确定。

谢谢

【问题讨论】:

【参考方案1】:

updateLight(resp)chan.on的回调函数中使用,当你声明chan.on时,lightState是未定义的。因此,每当触发chan.on 的回调时,setLightState 的值是未定义的(JS 关闭)。 如果你想使用之前的状态值设置新的状态,你需要传递一个函数给setLightState

setLightState(prevLightState => (...prevLightState, ...newState))

【讨论】:

这感觉太复杂了。我不明白为什么需要一个函数来简单地更新一个值。【参考方案2】:

当您使用useState 初始化您的状态时,您并没有为lightState 设置初始值。您可以将其初始化为空对象useState(),它应该可以工作。

另请参阅使用useCallback 在因变量发生变化时更新函数参数。

请参阅declaring a state variable 和useCallback 了解更多详情。

【讨论】:

不幸的是,这并不能解决问题,因为当我在后续渲染中设置状态时,它会忽略初始状态/将其加载为 undefined

以上是关于更新时反应钩子状态未定义的主要内容,如果未能解决你的问题,请参考以下文章

传递给子组件时道具未定义(反应钩子)

反应钩子。无法对未安装的组件执行 React 状态更新

反应 useState 钩子不使用 axios 调用更新

使用上下文和钩子更新未安装组件的状态 - 反应原生

使用 useQuery 进行批处理反应钩子返回未定义

用于获取数据的自定义反应钩子在第二次点击时未提供数据