渲染道具模式一直是在组件之间共享逻辑的一种流行方式。自React 16.8以来,自定义钩子是一种在组件之间共享逻辑的更优雅的方式。那么,现在不需要渲染道具了吗?不!不需要。渲染道具对于构建可重用的组件仍然很有用 ...
什么是渲染道具?
渲染道具是一个渲染东西的函数,即一个返回JSX的函数。
interface Props {
...
renderItem?: (item: string) => JSX.Element;
renderHeader?: () => JSX.Element;
}
它们可以用来委托组件的消费者对组件的某些部分进行渲染。这可以使一个组件非常灵活和高度可重复使用。
每个组件都已经有了一个渲染道具
每个React组件都有一个儿童道具。
export const Card: FC = ({ children }) => (
<div className="card">{children}</div>
);
这就是一个渲染道具!在上面的例子中,children 道具允许组件的消费者渲染卡片的内容。
<Card>
<p>Some interesting text</p>
<button>Click me</button>
</Card>
上面是一个消费Card 组件的例子。嵌套在Card 中的段落和按钮元素被提取为children 道具,并在卡片的div中进行渲染。

创建一个渲染道具
我们可以创建我们自己的渲染道具。
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 组件进行了扩展,使其拥有一个标题。消费者可以使用renderHeader 渲染道具来覆盖默认的外观。
<Card renderHeader={() => <h3>A custom header</h3>}>
<p>Some interesting text</p>
<button>Click me</button>
</Card>
上面是一个消费Card 组件的例子,它使用renderHeader 道具提供了头。我们只需将renderHeader 道具分配给一个内联箭头函数,该函数返回一个包含我们的标题的h3 。

我们现在开始理解渲染道具的力量,以及它是如何使一个组件变得超级灵活和可重用的。
可重用的列表
呈现道具的一个常见用例是列表组件。
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 组件,它有用于列表头和列表项的渲染道具。请注意,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 组件的例子。我们使用h3 渲染列表头,使用renderHeader 的道具。我们在span 中渲染每个数据项,并在旁边使用 "Click me "按钮,使用renderItem 道具。下面是结果。

很好!
总结
当我们创建高度可重用的组件,允许消费者渲染自定义元素时,渲染道具仍然非常有用。
每个React组件都自动有一个children 道具,允许消费者渲染组件的一个位。
我们可以在一个组件中创建我们自己的渲染道具,让消费者渲染组件的不同部分。
渲染道具可以接受参数,这在渲染道具被用来渲染数据项的集合时很有用。