微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当 React 功能组件重新渲染时,它会重新分配分配的值和功能吗?

如何解决当 React 功能组件重新渲染时,它会重新分配分配的值和功能吗?

如果像这样的代码useEffect 的依赖项重新渲染,

// ...
const Test = () => {
  // ...
  
  const value1 = "test1"
  
  const func1 = () => {
    // do something1
  }
  
  useEffect(() => {
    const value2 = "test2"
  
    const func2 = () => {
      // do something2
    }
  },[sth])
  
  return (
    // ...
  )
}

value1 & value2 & func1 & func2 是否重新分配给内存?

我对此很好奇,与优化有关。

解决方法

简短的回答,是的。每次函数运行时,旧值将被垃圾收集,新的原始值将分配到内存中,并创建对函数和对象的新引用。

但真正的问题是“不那么简短”的答案是“它是否以显着的方式影响性能?”。答案是……视情况而定。在大多数情况下,它不会 (see the doc about it)。但在某些情况下,您需要进行一些更改才能使用 useCallback 和使用 useMemo 进行性能优化。

还值得一提的是(如 Shivam Jha's answer 中所述)useEffect 中的触发器不一定会导致重新渲染(DOM 绘制),因为此过程首先发生在虚拟 DOM 上,并且只会在必要时持久化在真实的 DOM 中。

我将在此留下一些有关此讨论的其他参考资料。

Dan Abramov's tweet on memoizing everything(也看看回复)

Kent C. Dodds's article about render performance

Felix Gerschau's article about when render occurs

,

根据文档:

useEffect 有什么作用?通过使用这个 Hook,你告诉 React 你的组件需要在渲染后做一些事情。 React 会记住您传递的函数(我们将其称为“效果”),并在执行 DOM 更新后稍后调用它。在这个效果中,我们设置了文档标题,但我们也可以执行数据获取或调用其他一些命令式 API。

此外,它不会re-renders代码,而是在传递给它的依赖项发生变化时再次运行代码

Tip: Optimizing Performance by Skipping Effects 描述了解决由于在每次渲染后清理或应用效果而导致的性能问题。

此外,您可以使用 useEffect with cleanup 释放已分配的内存(如果未自动释放)或在运行代码 (setTimeOut,etc) 后运行一些副作用。 基本上在 return 函数中的 useEffect 之后执行您想要运行的所有操作:

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id,handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id,handleStatusChange);
    };
  });
,

value1 & value2 & func1 & func2 是否重新分配给内存?

简而言之,答案是肯定的。

如果你看看它是什么就更清楚了:Test 是一个函数,所以每次调用该函数时,函数作用域内的所有变量(大括号)都会重新声明并重新 -分配。

让我们深入了解细节:

value1func1 位于函数体中,因此每次调用函数时都会声明和分配它们,它们根本没有关系,它们只是同名。

value2func2 而是在具有声明依赖项 (sth) 的 useEffect 钩子中声明,这意味着这两个变量仅在第一次渲染之后和之后重新声明和重新分配如果 sth 变量与上一次渲染相比更改了其值,则每隔一次渲染。

如果您想优化 value1 使其在每次渲染时都不会改变,您可以这样使用 useMemo 钩子:

const value1 = React.useMemo(() => {
  return "test1"; //here you might have a more complicate way to determine value1
},[]); //array of dependencies like for `useEffect`,so `value1` will be recalculated only if any of the values provided in here change. by leaving it empty value1 will always be the **same** variable

您也可以使用 useCallback 钩子对函数进行类似的优化

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。