【问题标题】:What's the difference between functional component and create component using useMemo() in ReactReact 中函数式组件和使用 useMemo() 创建组件有什么区别
【发布时间】:2021-09-17 07:30:57
【问题描述】:

这两种组件构造方法是一样的吗?

const myComp=(props)=><h1>props.text</h1>

const myComp=useMemo((props)=><h1>props.text</h1>)

它们都在道具变化时呈现

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    简答

    • 使用不带依赖数组的useMemo 将无济于事。
    • 一般来说,不要使用useMemo来定义组件。
    • 为确保您正确使用 useMemo,请设置您的 linter,如 here

    长答案:

    先做两件事:

    请注意,useMemo 只能在另一个组件或钩子中使用(请参阅here),所以我将假设其余的答案。

    我想说您对useMemo 的使用不正确。如果你想用它定义一个组件(但你可能不应该)它可能是这样的:

      const MyComp = useMemo(
        () => (props) => (
          <h1>
            {props.text}
          </h1>
        ),[]
      );
    

    这定义了一个功能组件,并在依赖关系发生变化时重新定义它。 (这里的依赖是[],所以它只会被定义一次)。请注意,如果您按照here 的建议正确设置 linting,则使用不带依赖数组的 useMemo 会导致 linting 错误 (react-hooks/exhaustive-deps)。

    如果你坚持要省略依赖数组,useMemo 将无济于事。

    要玩一些不同的场景,看看这个codesandbox

      const MyCompA = (props) => (
        <h1>
          {props.text}
          {counter}
        </h1>
      );
    
      // Equivalent to MyCompA. Gives linting error
      const MyCompB = useMemo(() => (props) => (
        <h1>
          {props.text}
          {counter}
        </h1>
      ));
    
      // Will only be defined once and not notice changes to counter. Gives linting error
      const MyCompC = useMemo(
        () => (props) => (
          <h1>
            {props.text}
            {counter}
          </h1>
        ),
        []
      );
    
      // Will notice changes to counter. But generally, this  is not
      // much better than MyCompA
      const MyCompD = useMemo(
        () => (props) => (
          <h1>
            {props.text}
            {counter}
          </h1>
        ),
        [counter]
      );
    

    MyCompAMyCompB 做同样的事情,因为 MyCompB 使用 useMemo 没有依赖关系。 MyCompC 使用该状态 counter 但无法识别更改,因为它不在依赖数组中。 MyCompC 认识到这种变化,但总体上并不比 MyCompA 好多少。

    请注意,整个示例仅用于“玩耍目的”,因此我们可以检查 useMemo 的行为方式。一般来说,用useMemo 定义组件可能不是要走的路。对于该示例,最好使用将textcounter 作为道具的常规组件。

    【讨论】:

    • 我可以说用 useMemo(()=>..,[]) 定义 comp 与定义纯函数 comp 相同
    • 没有。正如您在代码框中看到的,当您更改计数器状态时,MyCompC 的行为与 MyCompA 不同。 (通过单击按钮)。 useMemo 使 MyCompC 无法识别状态变化。
    • 了解到现在由于计数器不在监视列表中,因此功能被记住了。精彩的试验场和答案。非常感谢。这些是在组件内定义的内部组件,非常罕见。但我看到你把所有这些测试用例都放在上面了。
    • 很高兴为您提供帮助。请注意,整个 useMemo 仅适用于其他组件。如果你想定义“新鲜”的非嵌套组件,useMemo 无论如何都不会工作。 linter 也会告诉你
    【解决方案2】:

    useMemo 在这种情况下不会影响函数调用以及组件对 prop 更改的反应方式。这可以通过useCallback 实现,但不推荐;这就是 memo 组件的用途。

    考虑到两者都是在组件函数中定义的,没有useMemo 的组件将在每次渲染时成为一个新组件,因此将被重新安装,而带有useMemo 的组件将按预期运行。

    由于组件不依赖于定义它的范围(这不是一个好的做法),它不应该在另一个组件中定义,因此不会从使用useMemo 中受益。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-18
      • 2019-09-21
      • 2021-02-03
      • 2020-04-04
      • 2020-06-01
      • 1970-01-01
      • 2019-03-28
      相关资源
      最近更新 更多