React 中的组件组合
介绍
使用 React 构建应用程序时,开发人员通常希望重用组件代码。刚接触 React 的开发人员通常会本能地尝试使用继承来实现这一点。然而,使用 React 的组合模型几乎总是更好的选择。
经常需要重复使用组件代码的组件的一个很好的例子是选项卡,这些选项卡在选择时会显示不同的内容。本指南将从一组不重复使用任何代码的选项卡开始,并构建专用组件、容器组件以及两者的组合,以通过组合实现重复使用。
标签
构建包含选项卡的组件的一个简单方法是执行以下操作:
<ul className="nav nav-tabs">
<li className="nav-item">
<button
className={`nav-link${selectedTabIndex === 0 ? " active" : ""}`}
onClick={() => setSelectedTabIndex(0)}
>
{"Tab 1"}
</button>
</li>
<li className="nav-item">
<button
className={`nav-link${selectedTabIndex === 1 ? " active" : ""}`}
onClick={() => setSelectedTabIndex(1)}
>
{"Tab 2"}
</button>
</li>
</ul>
<div className="tab-content">
{selectedTabIndex === 0 && (
<>
<h2>{"Tab 1"}</h2>
<p>{"Some content for the first tab"}</p>
</>)}
{selectedTabIndex === 1 && (
<>
<h2>{"Tab 2"}</h2>
<p>{"Some content for the second tab"}</p>
</>)}
</div>
ul元素分别包含每个选项卡的 UI,内容显示在底部的div元素中。这样没问题;但是,当需要新选项卡时,需要复制/粘贴代码,如果需要更改跨选项卡或内容的任何通用元素,则必须为每个选项卡更改它们,这并不理想。为了简化此过程,可以使用以下一种或两种模式的组合来组成选项卡组件。
专用组件
专用组件是一种通用组件,它接受用于呈现专用版本的 props。选项卡 UI 的专用组件如下所示:
const TabSpecialized = props => (
<li className="nav-item">
<button
className={`nav-link${props.selected ? " active" : ""}`}
onClick={props.onSelect}>
{props.text}
</button>
</li>);
此组件使用text、selected和onSelect属性来定义要在选项卡上显示的文本:一个布尔值,表示是否选择了选项卡,以及单击选项卡时要调用的函数。 然后可以像这样使用此选项卡组件:
<TabSpecialized
text="Tab 3"
selected={selectedTabIndex === 2}
onSelect={() => setSelectedTabIndex(2)}
/>
因此,如果需要改变选项卡的显示,则只需在SpecializedTab组件中进行一次更改,然后该更改就会反映在所有选项卡中。
类似地,可以使用专门的组件来表示选项卡内容:
const TabContentSpecialized = props => (
<>
<h2>{props.header}</h2>
<p>{props.paragraph}</p>
</>);
此组件接受header的 props ,用于显示 header 和一段文本。组件的使用方式如下:
<TabContentSpecialized
header="Tab 3"
paragraph="Some content for the third tab"
/>
这将在h2元素内呈现标题,然后是段落。
与选项卡组件一样,如果需要对标题或段落的显示方式进行任何更改,则只需在TabContentSpecialized组件中进行此更改。
容器组件
在许多情况下,一个专门的组件就足够了,但是,在这些选项卡组件中使用此模式的一个缺点是,它假定所有组件都将以相同的格式显示,并且实际上知道如何显示应用程序中每个选项卡的内容。 对于实际的选项卡组件,这很可能是正确的。 但是,对于内容,可能并非如此。 专门的内容组件采用标题和段落的字符串道具; 如果需要呈现其他任何内容,则可以将可选道具添加到组件以涵盖所有已知的情况,或者可以使用容器组件。 再次假设所有情况都是已知的,并且还会使组件代码非常复杂; 因此,容器组件是更好的选择。
所有 React 组件都有一个特殊的children prop,以便消费者可以通过将组件嵌套在 jsx 中来直接传递组件。标签内容组件可以使用此 prop 来接受实际内容,而无需了解任何其他信息。
作为容器的选项卡内容组件的版本如下所示:
const TabContentContainer = props => (
<div className="tab-content">
{props.children}
<div />);
这个组件只是在div内渲染子组件,用于确保内容以标准样式显示,使用方式如下:
<TabContentContainer>
<div className="tab4-content">
<img src={logo} className="App-logo" alt="logo" />
<p>This tab can contain anything.</p>
</div>
</TabContentContainer>
TabContentContainer元素内嵌套的所有内容都作为children属性传递,并由内容组件呈现,这意味着,正如文本所说,选项卡现在可以包含任何内容。
结合专用组件和容器组件
对于选项卡组件,专业化和容器的组合可能是最佳使用模式。这样,每个选项卡和内容都可以以相同的样式显示标题文本,但也可以使用 children属性来定义特定内容。
组合选项卡组件的代码如下所示:
const Tab = props => (
<li className="nav-item">
<button
className={`nav-link${props.selected ? " active" : ""}`}
onClick={props.onSelect}
>
{props.text}
{props.children}
</button>
</li>);
除了专门的选项卡组件的 props 之外,现在还有一个children prop,允许选项卡显示任何额外内容。因此,使用此组件向选项卡添加图像可以像这样完成:
<Tab
text="Tab 4"
selected={selectedTabIndex === 3}
onSelect={() => setSelectedTabIndex(3)}
>
<img src={logo} className="App-logo" alt="logo" />
</Tab>
内容组件如下所示:
const TabContent = props => (
<>
<h2>{props.header}</h2>
{props.children}
</>);
该组件为上面的TabContentContainer组件添加了一个header属性,可以像这样使用:
<TabContent header="Tab 4">
...
</TabContent>
然后将显示标题,然后显示子标题。
结论
React 强大的组合模型让开发者可以相对轻松地重复使用组件代码。本指南使用组合模式创建共享代码的选项卡组件,以提供一致的 UI,同时又足够灵活以允许不同的内容。
可以在此处找到使用组合来构建选项卡的示例应用程序。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~