react version: 15.5.0react
组件容许您将UI拆分为多个独立的,可重用的部分。网络
概念上,组件就相似于 JavaScript
函数。它们接收任意的输入(props
),返回用于描述屏幕显示内容的 React elements
。函数
最简单定义组件的方式,是编写一个 JavaScript
函数:网站
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
这个函数是一个合法的组件,由于它接收包含数据的单个 props
对象参数,返回了一个 React elements
。咱们称这种用JavaScript函数定义的组件为函数式组件。this
你也可使用 ES6 class 来定义组件:code
class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
上述两个组件在视图展现上是等同的。orm
在 下一章节 咱们会讨论类组件的一些附加特性。在这以前,咱们先使用函数式组件来简化演示。对象
以前,咱们仅仅遇到表示DOM标签的 React elements
:生命周期
const element = <div />;
然而,元素也能够表示用户定义的组件:ip
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') );
咱们回顾下这个例子中发生了什么:
<Welcome name="Sara" />
元素调用 ReactDOM.render()
。{name: 'Sara'}
做为属性调用 Welcome
组件。Welcome
组件将 <h1>Hello, Sara</h1>
元素做为结果返回。<h1>Hello, Sara</h1>
来更新DOM。警告:
老是用大写字母开头命名自定义组件
例如,
<div />
表示一个DOM标签,可是<Welcome />
表示一个组件,且须要做用域中存在Welcome
变量。
组件能够在其输出中引用其余组件。这使咱们能够对不一样级别的实现抽象为相同的组件。在 React
中,按钮、表单、对话框,屏幕都一般被抽象为组件。
例如,咱们能够建立 App
组件来渲染多个 Welcome
组件:
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') );
一般,新的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> ); }
它接收 author
(对象类型),text
(字符串)和 date
(日期) 做为属性,而后在社交网站上呈现一个评论。
因为多层嵌套,这个组件很难变化,且很难重用它其中的各个部分。咱们能够从中提取几个组件。
首先,咱们提取 Avatar
组件:
function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); }
Avatar
不须要知道谁会渲染它。这也是为何咱们使用 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
组件,用于在用户名旁边显示 Avator
:
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> ); }
提取组件多是看起来很繁琐的工做,可是在较大的应用程序中,可重用的组件可以付出更小的代价。
若是您的UI的一部分使用了几回(按钮,面板,头像)或者它自身就很复杂(App, Comment),它们则是拆分出可重用组件的最佳候选人,这是一个至关实用的经验法则。
当你定义一个组件时,它不该该修改本身的 props
。思考下面的 sum
函数。
function sum(a, b) { return a + b; }
这些不会修改输入参数,且当输入参数相同时,老是返回相同结果的函数被称之为 纯函数。
相比之下,如下的函数是不纯的,由于它改变了本身的输入:
function withdraw(account, amount) { account.total -= amount; }
React
很是灵活,可是也有一个严格的规则:
全部的React组件必须像纯函数那样使用 props
(也就是不要在组件内部修改 props
)
固然,应用程序的UI是动态的,能够随时间的推移而变化。在 下一节 中,咱们将介绍新的概念 state
。state
容许React组件根据用户操做,网络响应以及其余随时间推移产生的变化来修改组件输出,而不会违背该规则。