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

When React functional component re-render, does it reassign assigned values & functions?

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

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

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

很好奇,跟优化有关

根据文档:

What does useEffect do? By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative 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);
    };
  });

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

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

还值得一提(如 中所述),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

does value1 & value2 & func1 & func2 reassign to memory?

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

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

让我们深入了解细节:

value1func1 在函数体中,因此每次调用函数时都会声明和分配它们,它们根本不相关,它们具有相同的名称。

value2func2 在 useEffect 钩子内声明并声明依赖项 (sth),这意味着这两个变量仅在第一次渲染后才重新声明和重新分配如果 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 钩子

对函数进行类似的优化