使用钩子管理综合事件并从事件处理程序更新状态的正确方法是什么?

时间:2019-09-14 05:45:49

标签: reactjs

新手在这里做出反应,使用钩子从合成事件中管理状态并从事件处理程序中更新状态的正确方法是什么,我已经阅读了官方的react文档,但找不到特定信息。

这是我到目前为止尝试过的。

步骤1:声明hook变量,我们将使用该变量更新状态

const [state, setState] = React.useState(0);

步骤2:声明处理综合事件并更新状态的功能

const handleCopy = (e) => {
   setState(state+1);
   e.preventDefault();
};

步骤3:添加事件侦听器并将事件传递给函数

document.addEventListener('copy', (e) => handleCopy(e));

第4步:将状态传递给组件

<Component value={state}/>

虽然我在这里遇到的问题很少

  1. 状态更新未反映在组件中。但这似乎是在更新状态,因为console.log似乎正确地反映了状态。
  2. 随着时间的流逝,注册了太多事件监听器。

为了防止过多的事件监听器,我将addEventListener封装为只注册一次的条件

const [syntheticEventRegistered, setSyntheticEventRegistered] = React.useState(false);

if(!syntheticEventRegistered)
{
    document.addEventListener('copy', (e) => handleCopy(e));
    setSyntheticEventRegistered(true);
}

这确实解决了太多的事件侦听器,但是handleCopy函数现在仅反映默认状态。即状态= 0(而不是最新状态)也不会更新组件值。

1 个答案:

答案 0 :(得分:1)

建议在componentDidMount生命周期中注册事件侦听器。您可以在功能组件中使用useEffect挂钩。使用useEffect可以订阅和取消订阅en事件(在返回函数中)。这样可以防止多次注册。我创建了一个示例。

function sumOfMultiples(number) {
    let sum = 0;
    for(let i = 1; i < number; i++){
       if(i % 3 === 0 || i % 5 === 0){
        sum += i;
       }
    }   
    return sum;
 }
 
 console.time('t');
 console.log(sumOfMultiples(100000))
 console.timeEnd('t')

您可以在此处签出:https://codesandbox.io/s/little-rgb-dfre7

对我有用。如果您从右侧选择某项并按ctrl + c,则计数器会增加。