React UseEffect 与 window click eventListener 的奇怪行为

Weird behavior of React UseEffect with window click eventListener

我正在尝试实现一个简单的 window 点击计数器。它需要计算整个页面的点击次数,而不是像 <div onClick={() => handleClick()}></div>.

这样的单个元素的点击次数

我已经尝试过此代码的多种变体:

import React, { useState, useEffect } from 'react';
import $ from 'jquery';

function Test() {
  const [clicks, setClicks] = useState(0);

  function handleClick() {
    try {
      setClicks(() => clicks + 1);
    } catch (err) {
      console.error(err);
    }
  }

  useEffect(() => {
    console.log(clicks);
  }, [clicks]);

  useEffect(() => {
    $(window).on('click', handleClick);
    return () => {
      $(window).off('click', handleClick);
    };
  }, []);

  return (<div>{clicks}</div>);
}

export default Test;

第一个 useEffect 只是在每次更改时记录 click 状态变量,因此我可以看到发生了什么。第二个添加事件侦听器并在组件卸载时将其删除。 问题是它在第一次点击时工作得很好。第一个 useEffect 记录 1 并且 <div> 中的值更改为 1。但是,如果我继续点击,则不会发生任何其他事情。这种做法错了吗?

谢谢!

你有一个经典的 stale closure 问题。改用这个:

  setClicks((clicks) => clicks+ 1);

按照您的方式,您的 clicks 将始终引用第一个渲染的值;它从未更新过,因为你 运行 你的 useEffect 只有一次。