useEffect 每隔一次点击重新渲染两次

useEffect re-rendering twice on every other click

我正在尝试使用一个简单的 4 按钮组件来切换每个按钮的 class,这样一次只有 1 个按钮是 active。我在按钮上使用了以下代码。

<NavLink
          to="/"
          className={On ? "nav-link-active" : "nav-link"}
          onClick={() => {
            setOn(true);
          }}
        >

我在所有 4 个按钮上都使用状态,就像这样

const [On, setOn] = useState(false);
  const [On2, setOn2] = useState(false);
  const [On3, setOn3] = useState(false);
  const [On4, setOn4] = useState(false);

最后,我使用一个简单的 if 语句来确保一次只能有一个按钮保持活动状态。

useEffect(() => {
    console.log("useeffect");
    if (On === true) {
      setOn2(false);
      setOn3(false);
      setOn4(false);
    }
    if (On2 === true) {
      setOn(false);
      setOn3(false);
      setOn4(false);
    }
    if (On3 === true) {
      setOn2(false);
      setOn(false);
      setOn4(false);
    }
    if (On4 === true) {
      setOn(false);
      setOn3(false);
      setOn2(false);
    }
  }, [On, On2, On3, On4]);
// I know there's probably a better way to do this, it was just a quick fix.

这在大多数情况下都有效,除了问题是 useEffect() 会在每隔一次点击时 运行 两次。然后重置按钮。

我没有太多地使用 UseEffect(),所以我不确定为什么会这样。如何阻止它重新渲染两次?我的完整代码是 viewable here.

只使用一个状态变量而不是多个状态变量,因此您不需要任何 useEffect。您可以有一个指示当前“打开”按钮的索引,0 到 3,或 -1 表示 none(遵循通常的 JS 编号约定):

const [buttonOn, setButtonOn] = useState(-1);

然后,对于问题中的 JSX,请改用:

<NavLink
          to="/"
          className={buttonOn === 0 ? "nav-link-active" : "nav-link"}
          onClick={() => {
            setButtonOn(0);
          }}
        >

下一个 Nav 将有 buttonOn === 1 ?setButtonOn(1),等等

根据其他导航及其内容,您可以通过在映射器函数中使用索引而不是写出每个导航来减少重复。