【问题标题】:ReactJS: Adding event listeners to the HTML body element and using component's state from within those listenersReactJS:将事件侦听器添加到 HTML body 元素并在这些侦听器中使用组件的状态
【发布时间】:2019-11-16 23:46:58
【问题描述】:

我有以下问题: 我有一个具有某种状态的 React 函数组件:

const [state, setState] = React.useState({products: []})

产品集合是使用 useEffect 挂钩从数据库加载的:

React.useEffect(() => {
   db.products.toArray((result) => setState(prevState => ({...prevState, products: result})))
}, [])

我想在按下某些键时修改产品集合,但即使使用/聚焦其他一些组件,我也需要我的组件来获取键输入。所以我决定使用以下方法向 HTML 正文元素添加一个事件侦听器: document.body.addEventListener("keydown", handleKeyDown)

但是这里给我带来了一个问题。此事件侦听器无法正确查看状态。它看不到从数据库加载的集合,而只看到状态初始化中使用的空数组。我找到了一种解决方法。如果我用 useRef 替换 useState 它可以工作,但我发现这个解决方案丑陋和人为,因为更改由 useRef 创建的变量不会刷新视图,所以我必须显式刷新它。 我是以正确的方式做事还是有更“有机”的方式来实现 document.body 事件侦听器,以便它能够使用组件的状态?

提前感谢您的帮助

【问题讨论】:

  • 对于到底发生了什么听起来不是很清楚。您确定在调用事件侦听器之前从 db 更新状态吗?你到底在哪里添加事件监听器?
  • 可能还需要在状态更改时再次添加事件侦听器React.useEffect(() => {document.body.addEventListener("keydown", handleKeyDown)}, [products])
  • 谢谢先生。这正是我所需要的。

标签: reactjs react-hooks


【解决方案1】:

您可以在 useEffect 挂钩中附加和定义事件侦听器。

React.useEffect(() => {
    db.products.toArray((result) => setState(prevState => ({...prevState, products: result})))
    document.body.addEventListener('keydown', event => {
        // Your state variables should be in scope here
        setState(prevState => ({...prevState, key: event.key}))
    })
}, [])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2019-03-21
    • 2020-03-06
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多