組件能夠將UI切分紅一些的獨立的、可複用的部件,這樣你就只需專一於構建每個單獨的部件。
react
中的組件就像是一個函數,他能夠接收一個props對象
,並返回一個React
元素javascript
函數定義/類定義組件css
function welcome(props) { return <div>hello {props.name}</div>; }
該函數返回一個react組件,它接收一個對象props,並返回一個React元素,咱們將這種類型的組件成爲是函數定義組件
,是由於字面上看來,他就是一個javascript函數。html
class welcome extends React.Component{ render() { return <div>hello {this.props.name}</div>; } }
使用 ES6 class 來定義一個組件:java
上面兩種方法定義的組件是相同的。
組件渲染react
咱們以前遇到的react元素都是dom標籤。然而react元素也能夠是自定義的組件:babel
const element = <Welcome name="zjj" />;
當時一個自定義組件的時候,它會將jsx屬性轉換爲一個props
對象傳遞給該組件。app
function Welcome (props) { return <h1>hi, {props.name}</h1>; } const element = <Welcome name="zjj"> ReactDOM.render( element, document.getElementById('app') );
回顧一下上段代碼發生了什麼
1. 咱們對<Welcome name="Sara" />元素調用了ReactDOM.render()方法。 2. React將{name: 'Sara'}做爲props傳入並調用Welcome組件。 3. Welcome組件將<h1>Hello, Sara</h1>元素做爲結果返回。 4. React DOM將DOM更新爲<h1>Hello, Sara</h1>。
注意: 組件名稱必須以大寫字母開頭。
組合組件dom
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"></div> <script src="../react/react.js"></script> <script src="../react/react-dom.js"></script> <script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.js"></script> <script type="text/babel"> //組合組件 function Welcome (props) { return <h1>hi, {props.name}!</h1>; } function App() { return ( <div> <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" /> </div> ); } var element = <App />; ReactDOM.render( element, document.getElementById('app') ); </script> </body> </html>
注意: 組件的返回值只能有一個根元素。這也是咱們要用一個<div>來包裹全部<Welcome />元素的緣由。
提取組件函數
// 一個Comment組件:(頭像、名字、評論內容、時間) function Comment (props) { return ( <div> <div className="comment"> <img className="userinfo" src={props.author.avatorurl} alt={props.author.name} /> <div className="avator"> {props.author.name} </div> </div> <div className="comment-text">{props.text}</div> <div className="comment-date">{formatDate(props.date)}</div> </div> ) } function formatDate(date) { return date.toLocaleDateString(); } const comment = { date: new Date(), text: 'I hope you enjoy learning React!', author: { name: 'Hello Kitty', avatorurl: 'http://placekitten.com/g/64/64' } }; ReactDOM.render( <Comment date={comment.date} text={comment.text} author={comment.author} />, document.getElementById('app') );
這個組件因爲嵌套,變得難以被修改,可複用的部分也難以被複用。因此讓咱們從這個組件中提取出一些小組件。ui
function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); }
這樣就成了
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> ); }
咱們還能夠繼續提取
function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> ); }
這樣咱們的組件就是
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> ); }
props的可讀性
不管是使用函數或是類來聲明一個組件,它決不能修改它本身的props。props只是可讀的。
function withdraw(account, amount) { account.total -= amount; } // 不容許props被這種方式再組件中修改