React Hooks 比类组件使用更多内存吗?

问题描述 投票:0回答:2

我的理解是,Javascript 类将其方法存储在 Class 原型上,因此所有 Class 实例在调用这些方法时都在内存中使用相同的函数定义。即每个实例都使用内存中的单个函数定义。

对于 React Hooks,功能组件可以通过

useState()
返回的函数更新状态。例如

import React, { useState } from 'react'

function MyComponent(){
    const [greeting, setGreeting] = useState("Hello")

    return <h1>{greeting}</h1>
}

如果我的应用程序要渲染 100 个

MyComponents
,那么所有 100 个组件中的
setGreeting()
函数是否会引用内存中相同的
setGreeting()
函数,或者内存中是否会存在相同函数的 100 个副本?

javascript reactjs react-hooks
2个回答
4
投票

不,对于 100 个组件,将创建 100 个 setGreeting。SetGreeting 是函数的引用。所以会有 100 个参考。

请参考以下沙箱链接:https://codesandbox.io/s/eager-kowalevski-x20nl

说明:

在下面的代码中,我存储对 setName 函数的引用,只是为了验证它是否是相同的函数。我在窗口级别存储两个变量。如果存储第一个变量,我会将其存储在第二个变量中,以便稍后进行比较。当我比较这两个时,它们是不同的。我没有一次收到控制台消息说“true”。所以每次都会创建不同的函数。

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [name, setName] = useState("asutosh");
  if (window.s1) {
    window.s2 = setName;
  } else {
    window.s1 = setName;
  }
  console.log(window.s1 === window.s2);

  return (
    <div className="App">
      <h1>Hello {name}</h1>
    </div>
  );
}

0
投票

功能组件将在每次渲染时为功能重新分配内存。

对于基于类的组件,应该在构造函数中手动进行函数绑定:

constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
}

这使我们能够避免为类组件中的 onChange 函数分配内存。

另一方面,功能组件的 set 函数在每次渲染时始终是一个新实例。当功能组件重新渲染时,会创建 set 函数的新实例。

这是一个沙箱,确认了这一点:https://codesandbox.io/p/sandbox/frosty-pine-82klp8

import React, { useState } from "react";
import "./styles.css";

let prevFunction;

export default function App() {
  const [name, setName] = useState("asutosh");
  
  // Save reference to the setName function in a global variable
  if (!prevFunction) 
    prevFunction = setName;

  if (name == "asutosh") {
    // Force component re-render
    setTimeout(() => {
      setName("bawutosh");
    }, 1000);
  }

  return (
    <div className="App">
      <h1>Hello {name}</h1>
      <p>
        {prevFunction === setName
          ? "setName is the same"
          : "setName is different"}
      </p>
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.