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組件根據用戶操做,網絡響應以及其餘隨時間推移產生的變化來修改組件輸出,而不會違背該規則。