为什么 useEffect() 在这个简单的反例中不起作用?

why does useEffect() not work in this simple counter example?

这是我的代码:

import { useState, useEffect } from 'react';
export default function CompA() {
  const [counter, setCounter] = useState(0);

  const increment = () => {
    setCounter(counter + 1);
  };

  const isEven = useEffect(() => {
    return counter % 2 === 0;
  }, [counter]);
  return (
    <div>
      <button onClick={increment}> Counter {counter}</button>
      <h2>{isEven ? 'Even' : 'Odd'}</h2>
    </div>
  );
}

根据我有限的知识使用具有依赖性的 Effect 钩子,运行s 几次。首先在初始渲染中,然后当依赖数组中的计数器状态发生变化时。 随着状态值的每次变化,useEffect 重新渲染整个组件,以便我们可以直观地看到变化。

在这个简单的示例中,在初始渲染中 useEffect 应该 return True 或 False,然后基于这个值,h2 标签中的三元运算符应该相应地显示该值。

问题是,当我 运行 我的代码时,h2 标签仍然等于 ODD,即使我的初始计数器状态为 0。另外,按下按钮将改变计数器的值,并且 useEffect 应该执行并触发重新渲染。

但是,none 这些工作!这是为什么?我做错了什么吗?

useEffect 没有 return 任何东西,它对您想要做的事情没有用。由于 useEffect 没有 return 任何东西,isEvenundefined,这导致显示“奇数”。

我会像这样简单地编写一个内联计算:

const isEven = counter % 2 === 0;

useEffect 不需要使组件呈现,这就是调用 setCounter 的目的。当组件重新渲染时,此行将根据计数器的最新值计算 isEven。如果计算是一个非常昂贵的计算(不是)并且您想通过在没有任何变化的情况下跳过计算来提高性能,您可以使用 useMemo:

const isEven = useMemo(() => {
  return counter % 2 === 0;
}, [counter])

不过,对于像您正在执行的轻量级计算来说,这并不是必需的。

您不应将 useEffect 用作​​返回值。它 returns 一片空白。 可以看useEffect的typescript规范。

useEffect(effect: React.EffectCallback, deps?: React.DependencyList): void

当您单击调用增量处理程序的按钮时,更新组件计数器的本地状态。 你可以只拥有

const isEven = !(counter % 2)

并将其用作

<h2>{isEven ? 'Even' : 'Odd'}</h2>