reactjs - 通过 useEffect 附加的事件监听器中的值始终落后 React State 一步

标签 reactjs react-hooks

我有一个 queryTerm 变量作为 useEffect Hook 的依赖项。我还在同一个钩子(Hook)中注册了一个 handleKeyPress 事件监听器。

我面临一个问题,当 queryTerm 依赖项更改时,handleKeyPress 监听器中的 queryTerm 值始终落后于新值一步queryTerm 值。

我将如何同步两者?

import React, { useState, useEffect } from 'react'

const Test = () => {
  const [queryTerm, setQueryTerm] = useState('')

  const handleChange = (event) => {
    setQueryTerm(event.target.value)
  }

  useEffect(() => {
    console.log({ outside: queryTerm })

    const handleKeyPress = (event) => console.log({ inside: queryTerm })

    window.addEventListener('keydown', handleKeyPress)

    return () => window.removeEventListener('keydown', handleKeyPress)
    
  }, [queryTerm])

  return (
    <div className='App'>
      <input onChange={handleChange} />
    </div>
  )
}

export default Test

最佳答案

这里实际上有3个问题:

  1. "keydown""change"事件按一定顺序发生,因此如果您在第一次记录某些内容,它肯定不会受到第二次的影响
  2. 即使您更改状态并将其记录在同一事件监听器中,日志也不会受到状态更改的影响,因为后者仅在下一次渲染时有效;请参阅The useState set method is not reflecting a change immediately
  3. 当构建一个在其主体中使用某种状态的回调时,它实际上“嵌入”了该状态的陈旧值作为其闭包;将状态变量视为每个渲染的不同引用(前面的链接也解释了这一点);解决方法包括利用 useRef hook,不过要看具体情况

就您而言,尚不清楚为什么您需要在"keydown"上使用您的状态(以及为什么它必须附加到 window 而不是 <input/> ),并期望它反射(reflect) "change" 上发生的状态更改事件?

这可能是一个人为的示例,但实际上,您可以简单地执行以下操作:

const handleChange = (event) => {
  setQueryTerm(event.target.value)

  // 1. Do everything in the same event handler
  // 2. and 3. Use directly the new value
  // instead of reading the state that will
  // change only on next render
  console.log({ inside: event.target.value })
}

关于reactjs - 通过 useEffect 附加的事件监听器中的值始终落后 React State 一步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74870084/

相关文章:

reactjs - 如何检测react-native FlatList中屏幕上有什么项目?

javascript - 在没有 jQuery AJAX 的情况下在 React 中提交表单

reactjs - React router v4 history.push 到功能组件中的相同路由(不同的查询参数)(使用 Hooks API)

javascript - 使用 React.js 实现 SlideToggle 功能

javascript - 可恢复上传在 Android 后台失败 - React Native

reactjs - 如何使用本地存储、react hooks 和 Context Provider 保持状态持久

Reactjs useMemo 钩子(Hook)行为类似于 componentDidMount

javascript - 我需要帮助修复列表数组中的错误

javascript - React hooks - 从数组中删除多个对象并更新状态

javascript - useState/useReducer 的初始化函数必须是纯函数吗?