Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useEffect重复调用两次的坑 #58

Open
jtwang7 opened this issue Nov 24, 2022 · 0 comments
Open

useEffect重复调用两次的坑 #58

jtwang7 opened this issue Nov 24, 2022 · 0 comments

Comments

@jtwang7
Copy link
Owner

jtwang7 commented Nov 24, 2022

useEffect重复调用两次的坑

转载文章: useEffect重复调用两次的坑

前言

在项目开发过程中,遇到一个问题:

useEffect(() => { 
  console.log(1)
  return () => {
    console.log(2)
  }
}, [])

执行上述代码,React 组件挂载完成后,打印了 1 2 1。这意味着 useEffect 被连续调用了 2 次,这是不符合 useEffect 触发条件的。
后续找到了上述文章:罪魁祸首就是 React 脚手架自带的 StrictMode 模式。

React 严格模式 StrictMode

定义

StrictMode 是一个用来突出显示应用程序中潜在问题的工具。与 Fragment 一样,StrictMode 不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。

作用

StrictMode 目前有助于:

  • 识别不安全的生命周期
  • 关于使用过时字符串 ref API的警告
  • 关于使用废弃的 findDOMNode 方法的警告
  • 检测意外的副作用
  • 检测过时的 context API
  • 确保可复用的状态

副作用

严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过 故意重复调用(注意这里) 以下函数来实现的该操作:

  • class 组件的 constructor,render 以及 shouldComponentUpdate 方法
  • class 组件的生命周期方法 getDerivedStateFromProps
  • 函数组件体
  • 状态更新函数 (即 setState 的第一个参数)
  • 函数组件通过使用 useState,useMemo 或者 useReducer

看到其中的函数组件体,一切都真相大白了。原因就是react脚手架启动的项目默认会用严格模式包裹,而包裹后会使组件被调用两次。

在后面还解释了对于结果中那行打印出的浅灰色的---App---也给出了说明:
注意:在 React 17 中,React 会自动修改 console 的方法,例如 console.log(),在第二次调用生命周期函数时,将日志静默。然而,在某些情况下,这可能会导致一些不符合期望的行为发生,此时可以使用替代解决方案。
从 React 18 开始,React 不会抑制任何日志。不过,如果你安装了 React Dev Tools,第二次调用的日志会出现被轻微淡化。React DevTools 也提供了一个设置(默认关闭)来完全抑制它们。

React StrictMode 严格模式 只在开发模式下运行不会影响生产构建。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant