React+异步任务 的疑问

2021-10-21 11:26:04 +08:00
 johnkiller

背景:Vue 用户,重学 React 中

先上代码

function App() {
  const afterRender = () => {
    console.log('after render')
   }

  // 1.  渲染后回调
  // useEffect(afterRender)
  // 2.  尝试用异步方式模拟渲染后的回调
  queueMicrotask(afterRender)
  // Promise.resolve().then(afterRender)
  // setTimeout(afterRender, 0)


  return (
    <div className="App">
     <div>something</div>
    </div>
  )
}

问题在于:

useEffect 表现正常(废话),

而 2 中的 3 种方法,通过异步方式实现渲染后执行,afterRender 会被调用两次,即控制台打印两次after render

这到底是什么原因?

1498 次点击
所在节点    React
5 条回复
mxT52CRuqR6o5
2021-10-21 11:49:03 +08:00
可能是和 fiber/concurrent mode 有关,文档中的意思也是说在最终 patch 之前可能会 render 多次
sweetcola
2021-10-21 11:52:04 +08:00
分析了一下,不太对劲,不应该输出两次。在 codesandbox 里调试一下,确实只输出了一次。你的 React 版本是 18 并且用上了 Strict Mode 吗(我也没用过,不太确定)?
Kasumi20
2021-10-21 11:56:27 +08:00
Strict Mode
Kasumi20
2021-10-21 11:57:34 +08:00
严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过故意重复调用以下函数来实现的该操作:

class 组件的 constructor,render 以及 shouldComponentUpdate 方法
class 组件的生命周期方法 getDerivedStateFromProps
函数组件体
状态更新函数 (即 setState 的第一个参数)
函数组件通过使用 useState,useMemo 或者 useReducer
Chingim
2021-10-21 14:34:56 +08:00
我用 react17/react18 都复现不了呢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/809458

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX