【问题标题】:React Function Components with hooks vs Class ComponentsReact Function Components with hooks vs Class Components
【发布时间】:2019-04-03 09:39:01
【问题描述】:

随着在 React 中引入hooks,现在主要的困惑是何时使用带有钩子和类组件的函数组件,因为借助钩子,即使在函数组件中也可以得到state 和部分lifecycle hooks。所以,我有以下问题

  • 钩子的真正优势是什么?
  • 何时使用带有钩子的函数组件与类组件?

例如,带有钩子的函数组件无法像类组件那样帮助提高性能。他们不能跳过重新渲染,因为他们没有实现shouldComponentUpdate。还有什么原因吗?

提前致谢。

【问题讨论】:

  • 部分生命周期挂钩你从哪里得到的?我只是快速浏览了参考链接,它没有说明生命周期方法。据我所知,大多数人选择使用类组件是因为他们需要访问状态,而不知道它会为生命周期方法添加元。使用钩子,您应该有一个功能组件,其状态减去生命周期方法的开销。
  • 你应该检查Effect Hook。这更像是 componentDidMount 和 componentWillUnmount。
  • useEffect,增加了从函数组件执行副作用的能力。它的用途与 React 类中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 相同,但统一为一个 API,因此您无法访问任何生命周期方法。它是一个包装器,就像一个包装器,但你不能单独访问它们。
  • 关于类组件限制的总结:basefactor.com/react-class-components-pitfalls(这种管理,难以提取功能,在分离的处理程序中管理相关关注点,高阶组件使用噪音,从类组件切换到功能和反过来,学习接近的、基于类和函数的组件)。

标签: javascript reactjs react-hooks


【解决方案1】:

引入HooksReact.memoReact.lazy 等其他功能背后的想法是帮助减少必须编写的代码并将类似的操作聚合在一起。

文档没有提到使用 Hooks 而不是类的真正充分理由

很难在组件之间重用有状态逻辑 通常,当您使用 HOC 或 renderProps 时,当您尝试在 DevTools 中查看它时,您必须使用多个层次结构重构您的应用程序,Hooks 可以避免这种情况并帮助更清晰的代码

复杂的组件变得难以理解 通常与类互不相关的代码通常会放在一起,或者相关的代码往往会被分开,它变得越来越难以维护。这种情况的一个示例是事件侦听器,您在 componentDidMount 中添加侦听器并在 componentWillUnmount 中删除它们。 Hooks 让你将这两者结合起来

类会混淆人和机器对于类,您需要了解绑定和调用函数的上下文,这通常会导致混淆。

带有钩子的函数组件不能作为类的性能 组件可以。他们不能跳过重新渲染,因为他们没有 shouldComponentUpdate 已实现。

函数组件可以通过使用React.memo 以类似于React.PureComponent 与类的方式进行记忆,您可以将比较器函数作为第二个参数传递给React.memo,让您实现自定义比较器


这个想法是能够在Hooks 和其他实用程序的帮助下使用函数组件编写您可以使用 React 类组件编写的代码。 Hooks 可以涵盖类的所有用例,同时在提取、测试和重用代码方面提供更大的灵活性。

由于 hooks 还没有完全发布,建议不要对关键组件使用 hooks,从相对较小的组件开始,是的,你可以完全用函数组件替换类


但是,在 Suspense 用于数据获取之前,您仍然应该使用类组件而不是带有钩子的函数组件,这是一个原因。使用 useEffect 挂钩获取数据不如使用生命周期方法直观。

@DanAbramov 在他的一条推文中也提到钩子旨在与 Suspense 一起使用,在 suspense 出现之前最好使用 Class

【讨论】:

  • 最后一点,如果有人想知道如何做到这一点,那么最近的这个问题 (stackoverflow.com/questions/53059059/…) 中有一些带有钩子的 AJAX 请求示例
  • @horyd,当然我们可以使用 useEffect 进行 API 调用,但它们可能会变得混乱。我在回答中也提到了同样的内容
  • 挂钩的组件是自动记忆的还是仍然需要 react.memo?
  • @JoelHarkes Hooked 组件默认不会被记忆,你需要使用 React.memo 来做到这一点
  • @EricBurel 您可以使用useCallback 挂钩来记忆处理程序。请查看此帖子,如果您仍需要帮助,请告诉我
【解决方案2】:

官方听起来,钩子会完全取代类??也许有一天,但想想看; hooks 已经存在了 3 年(截至 2021 年 3 月),采用它们有利也有弊(利多于弊......不要误会我的意思)

我自己在状态管理/类方面有更多经验,经过大量研究和测试,我发现我们需要非常了解类和钩子。钩子只需要一小部分简单组件的代码,看起来非常适合优化 HOC。同时,类在路由、容器组件和异步编程等方面似乎更好。

我确信每种技术都有很多更好的情况,但我的观点是 程序员需要非常了解钩子和类,特别是在处理具有 100,000 多行代码和数百万用户的项目时。在这里阅读更多:https://stackoverflow.com/a/60134353/11239755

【讨论】:

    【解决方案3】:

    Hooks 大大减少了您需要编写的代码量并提高了它的可读性。

    值得注意的是,背后有隐藏的进程(就像组件确实挂载等),这意味着如果您不了解正在发生的事情,则可能难以排除故障。在实际项目中实施之前,最好先对它们进行试验并通读文档。

    与类相比,测试钩子的支持/文档​​仍然有限。 https://dev.to/theactualgivens/testing-react-hook-state-changes-2oga

    2020 年 8 月 28 日更新 使用带有自定义钩子的反应钩子测试库进行测试 https://github.com/testing-library/react-hooks-testing-library

    【讨论】:

      猜你喜欢
      • 2021-06-04
      • 1970-01-01
      • 2018-03-06
      • 2020-10-11
      • 2021-02-19
      • 1970-01-01
      • 2016-12-28
      • 2019-09-24
      相关资源
      最近更新 更多