组件可以让你将UI分割成独立的,可复用的模块,然后考虑将每个模块彼此隔离。
从概念上理解,组件就像js中的函数。他们接受随意的输入(被称为props)然后返回React元素来描述屏幕上应该出现什么。

函数式和类式组件

定义一个组件最简单的方法是写一个js函数:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}

这个函数是一个有效的React组件因为它接受一个props对象作为参数然后返回一个React元素。我们把这样的叫做函数式组件因为他们就是字面意思上js函数。

你也可以使用ES6的class来定义一个组件:

class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

从React的角度来看,以上两种方式定义的组件是一样的。

类定义这种方法有一些额外的特性我们在下一章节会讨论。在此之前,我们会使用函数来定义组件因为这样比较简洁。

渲染一个组件

先前,我们只遇到React元素代表DOM标签的情况:

const element = <div />;

然而,React元素也可以代表用户自定义组件:

const element = <Welcome name="Sara" />;

当React认为一个元素代表用户自定义组件时,它通过单个对象传递JSX属性到这个组件。我们叫这个对象为“props”。

举个例子,这段代码渲染“Hello, Sara”到页面上:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
} const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);

在CodePen中试一试

让我们概括一下在这个例子中到底发生了什么:

  1. 我们调用了ReactDOM.render()来渲染<Welcome name="Sara"/>元素。
  2. React调用Welcome组件并将{name: 'Sara'}这个对象作为props传入。
  3. Welcome组件返回了一个<h1>Hello, Sara</h1>元素作为结果。
  4. React DOM高效地更新了DOM来匹配<h1>Hello, Sara</h1>。

附加说明:

总是将组件名的首字母大写。

举个例子,<div/>代表一个DOM标签,但是<Welcome />代表一个一个组件并且需要Welcome定义或引入。

组合组件

组件可以在它的输出中引用其他组件。这样我们可以使用同一个组件抽象出任意等级的细节。一个按钮,一个表单,一个目录,一个对话框,整个屏幕内容:在React应用中,所有这些都同样表示为组件。

举个例子,我们创建一个渲染Welcome组件多次的App组件:

function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
} function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
} ReactDOM.render(
<App />,
document.getElementById('root')
);

在CodePen中试一试

通常,新的React应用有一个单独的App组件在最顶端。然而,如果你整合React到一个已经存在的应用里,也许你会从底开始通过小组件类似Button逐渐替换一直到最高级别。

附加说明:

组件必须返回一个单个的根元素。这就是为什么我们添加了一个<div>去包含所有<Welcome />元素。

提取组件

不要害怕将组件分割成更小的组件。

举个例子,看看这个Comment组件:

function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}

在CodePen里试一试

Comment组件接受了author(一个对象),text(一个字符串)和date(一个日期对象)作为属性,它在一个社会媒体网站上描述一段评论。

这个组件可以被简化因为嵌套的东西太多,它很难被复用。让我们从这里提取出一些组件。

首先,我们将提取Avatar:

function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}

Avatar组件不需要知道自己将要被渲染到Comment内部。这就是为什么我们给他的属性一个更通用的名字:user而不是author。

建议在命名属性名的时候从组件自己的角度来命名而不要从使用时的上下文环境来命名。

现在可以将Comment组件简化为更小的部分:

function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
接下来,我们将提取UserInfo组件,它内部渲染了一个Avatar旁边的用户名:
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}

这允许我们更进一步地简化Comment:

function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}

在CodePen中试一试

提取组件也许看起来像很枯燥的工作,但是拥有一系列可复用的组件会在大型应用中起到很好的效果。有一个很好的经验法则就是如果有一部分UI已经被使用多次(如Button,Panel,Avatar),或者组件本身已经足够复杂(如APP,FeedStory,Comment),那么使它成为一个可复用的组件会更合适。

props是只读的

如果你声明了一个组件使用函数或者类,那么它永远不能修改它自己的props。看看这个sum函数:

function sum(a, b) {
return a + b;
}

这样的函数被称为“纯函数”因为它们不尝试改变它们的输入,而且在输入同样的情况下一直返回一样的结果。

相比之下,这个函数就不是纯函数因为它改变了输入:

function withdraw(account, amount) {
account.total -= amount;
}
React是很灵活的但是它有一个严格的规定:
所有React组件必须是纯粹的函数不能改变props。
当然,应用的UI是随着时间动态变化的。在下一章节,我们会介绍一个新的概念叫做“state”。state允许React组件随着时间变化去改变他们的输出作为对用户动作的响应,网络的响应或者其他东西。state并没有违反这个规定。

React文档(五)组件和props的更多相关文章

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

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

  2. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素

    朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 [下载文本PDF进行阅读] 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得.助你在架构评审中过五关斩六将,助 ...

  3. DCloud-MUI:文档 UI组件

    ylbtech-DCloud-MUI:文档 UI组件 1.返回顶部 1.accordion(折叠面板) 折叠面板从二级列表中演化而来,dom结构和二级列表类似,如下: <ul class=&qu ...

  4. 一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)

    在目前的软件项目中,都会较多的使用到对文档的操作,用于记录和统计相关业务信息.由于系统自身提供了对文档的相关操作,所以在一定程度上极大的简化了软件使用者的工作量. 在.NET项目中如果用户提出了相关文 ...

  5. flexpaper 开源轻量级的在浏览器上显示各种文档的组件

    FlexPaper是一个开源轻量级的在浏览器上显示各种文档的组件,被设计用来与PDF2SWF一起使用, 使在Flex中显示PDF成为可能,而这个过程并无需PDF软件环境的支持.它可以被当做Flex的库 ...

  6. 推荐一套.NET文档处理组件Spire.Office

    原文:推荐一套.NET文档处理组件Spire.Office 以前的项目中用到一点Word简单处理的功能(文字替换和转PDF格式),当时使用的是一套COM组件,必须在服务器上安装office环境.最近考 ...

  7. GrapeCity Documents (服务端文档API组件) V3.0 正式发布

    近日,葡萄城GrapeCity Documents(服务端文档API组件)V3.0 正式发布! 该版本针对 Excel 文档.PDF 文档和 Word 文档的 API 全面更新,加入了用于生成 Exc ...

  8. GrapeCity Documents for Excel 文档API组件 V2.2 新特性介绍

    GrapeCity Documents for Excel 文档API组件 V2.2 正式发布,本次新版本包含诸多重量级产品功能,如:将带有形状的电子表格导出为 PDF.控制分页和电子表格内容.将Ex ...

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

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

  10. react文档demo实现输入展示搜索结果列表

    文档页面地址:https://doc.react-china.org/docs/thinking-in-react.html 该文档只给了具体实现思路,下面是我实现的代码. 初学react,如果有写的 ...

随机推荐

  1. SQLServer 取 字段名称 类型 字段描述 等

    https://www.cnblogs.com/w2011/archive/2013/01/04/2844143.html SELECT 字段名= convert(varchar(100), a.na ...

  2. 以结算价交易TAS和以市价交易TAM

    CME Group的合约规格中提到TAS和TAM交易,如:Gold Futures Contract Specs Gold 期货 合约规格 Trading at Settlement (TAS) is ...

  3. 【Mysql】key 、primary key 、unique key 与index区别

    参考:https://blog.csdn.net/nanamasuda/article/details/52543177 总的来说,primary key .unique key 这些key建立的同时 ...

  4. P1622 释放囚犯

    传送门 区间DP简介: 在写这题前,需要先弄清楚区间DP是如何操作的: 区间DP的做法还是相对固定的,没有其他类型DP的复杂多变.主要思想就是先在小区间进行DP得到最优解,然后再利用小区间的最优解合并 ...

  5. python 目录切换

    #- * -coding: utf - - * - import os, sys path = "c:\\" # 查看当前工作目录 retval = os.getcwd() pri ...

  6. jmeter学习四配置元件详解

    JMeter提供的配置元件中的HTTP属性管理器用于尽可能模拟浏览器行为,在HTTP协议层上发送给被测应用的http请求 1.Http信息头管理器 用于定制Sampler发出的HTTP请求的请求头的内 ...

  7. 使用pymongo连接mongodb时报错:pymongo.errors.OperationFailure: not authorized

    连接本机或局域网部署的mongodb时可以用以下方法: from urllib import parse from pymongo import MongoClient host = '*.*.*.* ...

  8. 本地Windows上安装 MySQL数据库

    1.首先下载mysql安装文件,下载地址:https://dev.mysql.com/downloads/mysql/ 2.将下载下来的压缩包解压到本地一个文件夹中 3.在文件根目录下新增my.ini ...

  9. 在vscode中,自定义代码片段,例vue组件的模板

    1---- 2----  输入vue,  选 vue.json 3----  在vue.json中编辑, 有说明 a.  tab符,要用空格, 也可以转义 4----   新建vue文件, 输入自定义 ...

  10. vue面试

    1.一个比较全的vue面试题 http://www.bslxx.com/p/3187.html