【问题标题】:react useEffect trigger although dependency value remain the same?反应useEffect触发器虽然依赖值保持不变?
【发布时间】:2019-12-14 07:09:25
【问题描述】:

为什么我没有执行 setTest 来更改测试值,但仍然触发日志?我预计第一次日志不应该触发,因为测试值保持为 0?

function App() {
  const [test, setTest ] = useState(0)

  useEffect(() => {
    console.log('log')
  }, [test])

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

我有一个这样的场景。在第一次加载时不做任何事情,然后如果用户在页面上选择一个选项然后做某事,我该如何使用 useEffect 来做到这一点?

【问题讨论】:

  • 它总是第一次运行。
  • @Domino987 我必须比较前一个值和当前值吗?我如何用钩子做到这一点?
  • UseEffect 为您比较 prev 和 current 值(作为第二个参数传递的值)。在第一次渲染中,prev 值是未定义的,因此它与当前值不同。这就是它被执行的原因。
  • @Domino987 问题不在于它被执行的原因,我想摆脱警告。

标签: javascript reactjs


【解决方案1】:

来自 https:Using the Effect Hook

useEffect 有什么作用?通过使用这个 Hook,你告诉 React 你的 组件需要在渲染后做一些事情。 React 会记住 您传递的函数(我们将其称为“效果”),然后调用它 稍后执行 DOM 更新。

您的组件已渲染,useEffect 已触发,并且您的日志已运行。

听起来您可能会将useEffect(只接受一个参数,一个回调)与其他接受多个参数的钩子混淆。

---- 编辑(评论相关)----

useEffect不是直接替代基于类的componentDidMountcomponentDidUpdate 方法,但由于运行时间的原因,它通常可以用来替代这些方法。 See 了解更多信息。您可能还想了解相关的 useLayoutEffect 钩子。

如果您的意图是在“加载”时连接一些逻辑,例如事件处理程序,则不需要挂钩来执行此操作。相反,您只需要一个 React 事件处理程序属性,例如。

<option onChange={changeHandler} />

See 了解更多信息。)

【讨论】:

  • 我认为useEffect就像componentDidUpdate?说我想在测试更改时触发 http 请求,我该如何使用 useEffect?
  • 它们并不完全相同,但useEffect 可以在许多相同的情况下使用。来自reactjs.org/docs/hooks-reference.html#useeffect:“与 componentDidMount 和 componentDidUpdate 不同,传递给 useEffect 的函数在延迟事件期间在布局和绘制之后触发。这使其适用于许多常见的副作用,例如设置订阅和事件处理程序,因为大多数类型的工作不应阻止浏览器更新屏幕。”
  • 另见useLayoutEffect。从同一个 URL:“提示如果您要从类组件迁移代码,请注意 useLayoutEffect 在与 componentDidMount 和 componentDidUpdate 相同的阶段触发。但是,我们建议先从 useEffect 开始 并且只有在导致问题时才尝试 useLayoutEffect。”
  • 我有一个这样的场景。在第一次加载时不做任何事情,然后如果用户在页面上选择一个选项然后做某事,我该如何使用 useEffect 做到这一点?
  • 简而言之,您不会:useEffect 是该工作的错误工具。相反,您想在您的选项上使用change(或blur,或类似的)事件处理程序来触发该逻辑。见:reactjs.org/docs/handling-events.html
【解决方案2】:

(1)第一个 useEffect 调用是在组件挂载时。

useEffect(() => {
    console.log('log')
  }, [test])

(2)如果您将第二个 Array 依赖项参数传递给 useEffect 并且该参数不为空,那么任何时候该依赖项更改之一都会调用 useEffect。

useEffect(() => {
    console.log('log')
  }, [test])

(3) 如果依赖数组为空,则仅调用一次useEffect(在组件第一次挂载后)。

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

(4)如果 useEffect 在没有第二个参数的情况下实现,任何时候组件状态更新 useEffect 也被调用。

useEffect(() => {
    console.log('log')
  })

根据您的情况,您可以检查 test 是否为 0 取消执行 useEffect 正文代码,如下所示:

function App() {
  const [test, setTest ] = useState(0)

  useEffect(() => {
   if(test < 1) return;
    console.log('log')
  }, [test])


  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

【讨论】:

  • @RachelV,别无礼。他只是想提供帮助,而他的最后一个代码段正是您所需要的。此外,您的问题是重复的,所以下次请检查该问题是否已有答案。
猜你喜欢
  • 2020-04-23
  • 2022-06-10
  • 2023-01-26
  • 2021-07-17
  • 2021-08-29
  • 2021-03-05
  • 2020-05-18
  • 1970-01-01
  • 2021-05-16
相关资源
最近更新 更多