组件能够将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被这种方式再组件中修改