React拥有很强大的组合模型,我们建议使用组合来替代继承来重利用组件之间的代码。

在本章节中,我们将讨论一些开发者经常触及继承的问题,并且我们该如何使用组合来解决这些问题。

组合

一些组件事先不知道它们的子组件。这种问题特别对于组件类似Sidebar或者Dialog这种通用的“盒子”。

我们建议像这样的组件使用特殊的children属性去直接传递子元素到它们的输出里:

function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}

这样的代码传递任意子组件给其他组件通过嵌套的JSX:

function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}

在CodePen里试一试

任何在<FancyBorder>JSX标签的东西被作为一个children属性传递给FancyBorder组件。当FancyBorder组件在一个div里渲染了{props.children},传递来的元素会出现在最终的输出里。

然而很少有相同的情况,有时你也许需要在一个组件里有多个“入口”。在这样的情况下你也许会想出你自己的约定来替代children属性:

function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
} function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}

在CodePen里试一试

像<Contacts />和<Chat />这样的React元素都是对象,所以你可以就像其他数据一样将他们作为props传递。

特殊实例

有时某些组件会是其他组件的特殊情况。举个例子,我们可以说一个WelcomeDialog组件是Dialog组件的特殊情况。

在React里,这样的也是由组合来实现,一个更加“特殊的”组件会渲染一个更加“通用”的组件并且用props来配置它:

function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
} function WelcomeDialog() {
return (
<Dialog
title="Welcome"
message="Thank you for visiting our spacecraft!" />
);
}

在CodePen里试一试

组合对于定义为类的组件同样做得很好。

function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
} class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
} render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>
);
} handleChange(e) {
this.setState({login: e.target.value});
} handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
}
}

在CodePen里试一试

那么继承怎么样?

在Facebook网站,我们使用React制作了上千个组件,但是我们还未找到将会建议创建继承层次的情况。

props和组合给了你所有的灵活性来让你通过明确的和安全的方式自定义组件的样子和行为。记住组件可能接受任意props,包括简单的values,React elements或者函数。

如果你想要在组件之间复用与UI无关的功能,我们建议将它提取到一个单独的js模块里。这样可以在不对组件进行扩展的前提下导入并使用该函数、对象或类。

React文档(十二)组合vs继承的更多相关文章

  1. React文档(二十四)高阶组件

    高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...

  2. React文档(二十二)context

    React中,通过React组件可以很容易地追踪数据流.当你关注一个组件,你可以发现哪一个props被传递了,这样使得你的应用很容被推断. 在一些情况下,你想要传递数据通过组件树而不需要去手动在每一层 ...

  3. React文档(二十)不使用JSX

    JSX并不是使用React的一个强制需求.当你不需要在你的构造环境里设置编译那么不使用JSX会很方便. 每一个JSX元素只是调用React.createElement(componnet, props ...

  4. React文档(二十一)协调

    React提供了一个声明式地API因此你不用担心每一次更新什么东西改变了.这使得开发应用变得简单,但是这个东西在React中如何实现的并不是很明显.这篇文章会解释我们在React的算法中所做的选择以便 ...

  5. React文档(二十三)Web Components

    React和web components是为了解决不同问题而创立的.web components为可重用组件提供了健壮的封装,而React提供了声明式的库来保持DOM和数据同步.这两点是互相补充的.作 ...

  6. React文档(二)Hello World

    开始学习React最简单的实践就是去试一试CodePen上面的Hello World程序.你不需要安装任何东西,只要新开一个标签页打开例子依照原例操作即可.如果你更喜欢在本地开发,那么来看看安装的介绍 ...

  7. React文档(十三)思考React

    在我们的看来,React是使用js创建大型快速网站应用的首要方法.它在Facebook和Instagram的使用已经为我们展现了它自己. React的一个很好的地方就在于当你创建应用的时候它使你思考如 ...

  8. “全栈2019”Java第五十二章:继承与初始化详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. GameUnity 2.0 文档(二) 纸片人系统

    本想快速的 把 之前写的类库,一股脑的 给大家 ,但又觉得,如 msdn那样的 文档,并不能给 初学者 所能接受. 因为 大部分人 对 api 还是比较陌生,也不愿意 去研究和组合. 那么 今天我选用 ...

  10. 浅谈用java解析xml文档(二)

    上一文中总结了dom解析xml文档的方式,本文开始总结使用SAX解析xml 的方式及它的优缺点! SAX(Simple API for XML),是指一种接口,或者一个软件包. 首先我们应该知道SAX ...

随机推荐

  1. 列表 & 元组& join & range

    一:列表(增删改查,列表的嵌套,列表的循环) 1)增加 append    (在列表的尾部增加) insert       (插入)   insert(插入的位置,插入的内容) extend      ...

  2. ARGB 颜色取值与透明度对照表

    1.  ARGB 依次代表透明度(alpha).红色(red).绿色(green).蓝色(blue). 2. 透明度分为256阶(0-255),计算机上用16进制表示为(00-ff).透明就是0阶,不 ...

  3. mysql /tmp目录爆满问题的处理

    mysql /tmp目录爆满问题的处理 突然收到zabbix告警,说mysql服务器的/目录磁盘空间不足. 登录到服务器,看了下发现100GB的根目录,居然使用了差不多90GB.这台服务器上只跑了一个 ...

  4. C#设计模式(2)——简单工厂模式(转)

    C#设计模式(2)——简单工厂模式   一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理 ...

  5. Vue系列之 => 评论功能(小知识点串联)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 单端测序(Single-read)和双端测序(Paired-end和Mate-pair)的关系

    https://blog.csdn.net/hanli1992/article/details/82982434

  7. bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requested: lxml.

    python3 bs4解析网页时报错: bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requeste ...

  8. python selenium基于显示等待封装的一些常用方法

    import os import time from PIL import Image from selenium import webdriver from appium import webdri ...

  9. springmvc学习路线1-基本配置

    1.第一个springmvc实例helloword 关键点拨 1.1 web.xml文件的配置 <servlet> <servlet-name>springMVC</se ...

  10. LSTMs 长短期记忆网络系列

    RNN的长期依赖问题 什么是长期依赖? 长期依赖是指当前系统的状态,可能受很长时间之前系统状态的影响,是RNN中无法解决的一个问题. 如果从(1) “ 这块冰糖味道真?”来预测下一个词,是很容易得出“ ...