React API 和代码重用的演变!( 二 )

  • 难以静态类型检查:当多个嵌套的 HOC 将新的 props 注入到包装的组件中时,正确的 props 输入很难保证 。
  • 数据流模糊:对于 mixins,问题是“这个状态从哪里来?”;对于 HOC,问题是“这些 props 从哪里来?” 。因为它们是在模块级别静态组合的,所以很难跟踪数据流 。
  • 除了这些陷阱之外,过度使用 HOC 还导致了深度嵌套和复杂的组件层次结构以及难以调试的性能问题 。
    Render propsrender prop 模式作为 HOC 的替代品出现,这种模式由开源 API 如 React-Motion 和 downshift 以及构建 React Router 的开发人员推广普及 。
    <Motion style={{ x: 10 }}>{interpolatingStyle => <div style={interpolatingStyle} />}</Motion>主要思想就是将一个函数作为 props 传递给组件 。然后组件会在内部调用该函数,并传递数据和方法,将控制反转回函数以继续渲染它们想要的内容 。
    与 HOC 不同,组合发生在 JSX 内部的运行时,而不是静态模块范围内 。它们没有名称冲突,因为很明确知道是从哪里来的,也更容易进行静态类型检查 。
    但是,当用作数据提供者时,它们可能会导致深度嵌套,创建一个虚假的组件层次结构:
    <UserProvider>{user => (<UserPreferences user={user}>{userPreferences => (<Project user={user}>{project => (<IssueTracker project={project}>{issues => (<Notification user={user}>{notifications => (<TimeTracker user={user}>{timeData =https://www.isolves.com/it/cxkf/bk/2023-05-29/> ({teamMembers => ( (// ...)}/>)})})})})})})}这时,通常会将管理状态的组件与渲染 UI 的组件分开来处理 。随着 Hooks 的出现,“容器”和“展示性”组件模式已经不再流行 。但值得一提的是,这种模式在服务逇组件中有所复兴 。
    目前,render props 仍然是创建可组合组件 API 的有效模式 。
    HooksHooks 在 React 16.8 版本中成为了官方的重用逻辑的方式,巩固了将函数组件作为编写组件的推荐方式 。
    Hooks 让在组件中重用和组合逻辑变得更加简单明了 。相比于类组件,在其中封装并共享逻辑会更加棘手,因为它们可能分散在各种生命周期方法中的不同部分 。
    深度嵌套的结构可以被简化和扁平化 。搭配 TypeScript,Hook 也很容易进行类型化 。
    function Example() {const user = useUser();const userPreferences = useUserPreferences(user);const project = useProject(user);const issues = useIssueTracker(project);const notifications = useNotification(user);const timeData = https://www.isolves.com/it/cxkf/bk/2023-05-29/useTimeTracker(user);const teamMembers = useTeamMembers(project);return (
    {/* 渲染内容 */}
    );}
    权衡利弊使用 Hooks 带来了很多好处,它们解决了类中的一些问题,但也需要付出一定的代价,下面来深入了解一下 。
    类 vs 函数从组件消费者的角度来看,类组件到函数组件的转变并没有改变渲染 JSX 的方式 。不过两种方式的思想是不同的:
    • 类与有状态类的面向对象编程有着紧密联系 。
    • 函数则与函数式编程以及纯函数等概念有关联 。
    React 中的组件概念,以及使用 JavaScript 实现它的方式,以及我们试图使用现有术语来解释它,都增加了学习 React 的开发人员建立准确思维模型的困难度 。对理解的漏洞会导致代码出现 bug 。在这个过渡阶段中,一些常见的问题包括设置状态或获取数据时的无限循环,以及读取过时的 props 和 state 。指令式响应事件和生命周期常常引入了不必要的状态副作用,我们可能并不需要它们 。
    开发者体验在使用类组件时,有一套不同的术语,如 componenDid、componentWill、shouldComponent和将方法绑定到实例中 。函数和 Hooks 通过移除外部类简化了这一点,使我们能够专注于渲染函数 。每次渲染都会重新创建所有内容,因此需要能够在渲染周期之间保留一些内容 。useCallback 和 useMemo 这样的 API 被引入就方便定义哪些内容应该在重新渲染之间保留下来 。
    在 Hooks 中需要明确管理依赖数组,再加上 hooks API 的语法复杂,对一些人来说富有挑战性 。对其他人来说,hooks 大大简化了他们对 React 的思维模型和代码的理解 。
    实验性 React forget 旨在通过预编译 React 组件来改善开发者体验,从而消除手动记忆和管理依赖项数组,强调将事情明确化或尝试在幕后处理事情之间的权衡 。


    推荐阅读