useEffect 挂钩如何以相同状态的更改为条件更改状态?

时间:2021-06-09 10:22:42

标签: javascript reactjs react-hooks

我有一个 useEffect 钩子,它在标题等于 project.name 时禁用:

    useEffect(() => {
        if (title === project.name) {
          setDisabled(false);
        } else {
          setDisabled(true);
        }
      }, [disabled]);

这很好用,但我不明白它是如何工作的。根据我的理解,useEffect 钩子的第二个参数指定了需要更改才能发生效果的变量。 disabled 在代码中的任何地方都没有改变,只是在效果本身。

从我的逻辑来看,这意味着 disabled 永远不会改变,因为条件先于效果。

2 个答案:

答案 0 :(得分:2)

您的情况发生了什么,您的应用程序呈现两次

事实上,对于每个副作用(例如,数据获取、手动更改 DOM 等),您的应用程序都将被重新渲染,这将调用钩子 (useEffect)。

效果总是在渲染阶段完成后执行,即使您在一个效果中设置了状态,另一个效果将读取更新的状态并仅在渲染阶段之后对其采取行动。

useEffect 类似于 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。

setState(即 setDisabled)还将重新渲染应用程序,因此您将重新执行 useEffect 钩子。

但是

如果调用 setState 的值与之前相同,则不会重新渲染函数组件(不会调用函数组件)。

场景:

  1. 在第一次渲染时,title !== project.name(假设是这样),所以我们将进入(title !== project.name) 块代码,我们将调用setDisabled( true)... 最后一次调用将再次重新渲染应用程序。

  2. 在第二次渲染时,现在我们有了title === project.name,所以我们将进入(title === project.name) 块代码,我们将调用setDisabled( false) ... 此调用还将重新渲染应用程序一次。

  3. 现在,由于我们已经设置了title === project.name,所以我们将再次进入(title === project.name)的块代码,我们将回忆setDisabled( false),但具有相同的值,因此应用程序不会再次重新渲染

答案 1 :(得分:1)

如果您想更改为禁用状态,也许您需要听到“title”,useEffect 钩子的第二个参数指定需要听到的变量才能发生效果。

useEffect(() => {
  if (title === project.name) {
    setDisabled(false);
  } else {
    setDisabled(true);
  }
}, [title]);