React Hooks 出现后,Render props 还有用么

render props 是一个非常流行的用于组件之间逻辑复用的开发模式,自从 React 16.8 出现了 自定义 Hook,并用于组件之间的逻辑复用后,render props 是不是就不再被需要了呢? 答案是 NO! render props 对于构建可重用的组件仍然有用

什么是 render prop

一个 render prop 是一个函数类型的组件属性(prop),该函数的返回值用于渲染一些东西,比如渲染一个 JSX

interface Props {
  ...
  renderItem?: (item: string) => JSX.Element;
  renderHeader?: () => JSX.Element;
}
复制代码

这样做可以让组件的使用者来决定某一个具体的位置需要渲染什么。 这就使组件非常灵活且高度可重用。

每一个组件都有一个 render prop

每一个组件都有一个 children属性

export const Card: FC = ({ children }) => (
  <div className="card">{children}</div>
);
复制代码

children 就是一个 render prop, 在上面的示例中,children 属性允许组件的使用者渲染自定义的内容。如:

<Card>
  <p>Some interesting text</p>
  <button>Click me</button>
</Card>
复制代码

创建 render prop

让我们创建自己的 render prop

interface Props {
  title?: string;
  renderHeader?: () => JSX.Element;
}
export const Card: FC<Props> = ({ children, title, renderHeader }) => (
  <div className="card">
    <div className="card-header">
      {renderHeader ? renderHeader() : title !== undefined ? title : null}
    </div>
    <div className="card-content">{children}</div>
  </div>
);
复制代码

我们的Card组件组件有一个头部(header),使用者可以使用 renderHeader 覆盖头部的默认展示效果

下面看看如何使用Card组件

<Card renderHeader={() => <h3>A custom header</h3>}>
  <p>Some interesting text</p>
  <button>Click me</button>
</Card>
复制代码

上面是一个 在Card组件中使用renderHeader 属性自定义渲染头部效果的例子,renderHeader属性是一个箭头函数,并返回一个h3标签包裹的内容

React Hooks 出现后,Render props 还有用么

现在,我们开始了解 render props 的作用以及让它如何在组件中具有超级的灵活性和可重用性。

创建一个可以重用的列表组件

interface Props {
  data: string[];
  renderItem?: (item: string) => JSX.Element;
  renderHeader?: () => JSX.Element;
}
export const List: FC<Props> = ({ data, renderItem, renderHeader }) => (
  <div className="list">
    <div className="list-header">{renderHeader && renderHeader()}</div>
    <ul>
      {data.map((item) => (
        <li key={item}>{renderItem ? renderItem(item) : item}</li>
      ))}
    </ul>
  </div>
);
复制代码

上面是一个简单的List组件,此组件有两个 render prop-renderItemrenderHeader。注意renderItem有一个参数,此参数被用来显示界面上

<List
  data={["Fred", "Bob", "Jane"]}
  renderHeader={() => <h3>Names</h3>}
  renderItem={(item) => (
    <div>
      <span style={{ marginRight: "10px" }}>{item}</span>
      <button>Click me</button>
    </div>
  )}
/>
复制代码

上面试使用List组件的一个例子,

  • 使用 renderHeader属性作为一个箭头函数并 h3包裹的内容
  • 使用renderItem属性返回列表的每一项并且与一个 按钮组件在一起,作为每一行数据的渲染结果

React Hooks 出现后,Render props 还有用么

总结

  • 当组件使用者需要在高度可重用的组件中渲染自定义组元素时, render props 仍然是非常有用的

  • 每个 React 组件都会有一个 render prop- children,以允许使用者在组件的某个位置渲染自定义元素。

  • 我们可以在组件中创建我们自己的 render props,以允许使用者在组件的多个不同位置渲染自定义元素。

  • render props 可以接受一些参数,这些参数在使用 render prop 来渲染数据项列表时非常有用。

参考文档:Render props are still useful | Building SPAs

上一篇:Shiro基础学习篇01


下一篇:2022年前端React的100道面试题的第6题:Class组件挂载时生命周期