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. Spark入门到精通--(第二节)Scala编程详解基础语法

    Scala是什么? Scala是以实现scaleable language为初衷设计出来的一门语言.官方中,称它是object-oriented language和functional languag ...

  2. property 和 魔法方法

    property和魔法方法 一.property 二.model,class,bases,mro 三.__doc__, __dict__,__call__,__item__,__len__,__str ...

  3. [js]js中4种无节操的预解释情况

    js中4种无节操的预解释情况 - 1. if语句即使条件不成立,条件里的表达式也会进行预解释. - 2. 匿名函数的预解释: 只对等号左边与解释 - 3. 自执行函数的预解释: 不进行预就解释, 执行 ...

  4. Python openpyxl、pandas操作Excel方法简介与具体实例

    本篇重点讲解windows系统下 Python3.5中第三方excel操作库-openpyxl: 其实Python第三方库有很多可以操作Excel,如:xlrd,xlwt,xlwings甚至注明的数据 ...

  5. Linux下安装jieba

    Jieba代码对 Python 2/3 均兼容 * 全自动安装:`easy_install jieba` 或者 `pip install jieba` / `pip3 install jieba` * ...

  6. Oracle 10g收集数据库统计信息

    1.需求概述 2.实施步骤 3.回退方案 1.需求概述 某数据库由于整体统计信息不准确,多次出现部分业务SQL选错执行计划,从而导致性能下降影响到最终用户体验,目前通过SQL_PROFILE绑定执行计 ...

  7. Java第二次考试

    代码 package sizeyunsuan; import java.io.FileNotFoundException; import java.io.PrintStream; import jav ...

  8. angular中的MVC思想

    MVC是一种使用 MVC(Model View Controller 模型-视图-控制器)设计模式,该模型的理念也被许多框架所吸纳.在学习angular的过程中,我在网上查找关于angular MVC ...

  9. idea显示左边的树形项目结构

    直接上步骤: File-->Project Structure-->Modules-->点击:中间一列框的"+"-->Import Module--> ...

  10. ANNOTATION 注解

    注解(Annotation)很重要,未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是 ...