007-组件和Props
一、概述
组件让你可以将用户界面分成独立的,可重复使用的部分,并且可以独立思考每个部分。
从概念上讲,组件就像JavaScript函数一样。他们接受任意输入(称为“props”)并返回描述屏幕上应显示内容的React元素。
1.1、功能和类组件
函数【方法】和类都能定义组件
1.1.1、函数方式定义
定义组件的最简单方法是编写一个JavaScript函数:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
这个函数是一个有效的React组件,因为它接受一个包含数据的“props”(代表属性)对象参数并返回一个React元素。我们称这些组件为“功能性”,因为它们实际上是JavaScript功能。
1.1.2、ES6 类方式定义
也可以使用ES6类来定义组件:
class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
以上两个组件与React的观点相同。 类有一些额外的功能
1.2、渲染一个组件
以前,我们只遇到了表示DOM标签的React元素:
const element = <div />;
但是,元素也可以表示用户定义的组件:【其中WelCome是1.1所定义的组件,name为参数属性】
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') );
调用过程:
1、使用<Welcome name="Sara" />
元素调用了ReactDOM.render()方法
2、React调用带有{name:'Sara'}的WelCome组件作为props。
3、WelCome组件返回一个<h1> Hello,Sara </ h1>元素作为结果。
4、React DOM有效地更新DOM以匹配<h1> Hello,Sara </ h1>。
注意:始终使用大写字母开始组件名称。
React将以小写字母开头的组件视为DOM标签。例如,<div />表示一个HTML div标签,但<Welcome />表示一个组件,并且要求Welcome属于范围。
1.3、复杂组件
组件可以在其输出中引用其他组件。这让我们可以对任何细节级别使用相同的组件抽象。一个按钮,一个窗体,一个对话框,一个屏幕:在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') );
通常,新的React应用程序在顶部有一个应用程序组件。但是,如果您将React集成到现有的应用程序中,则可以使用Button之类的小组件自下而上地开始,并逐渐走向视图层次结构的顶部。
1.4、提取组件
不要害怕将组件分解成更小的组件。
示例参看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
(an object), text
(a string), and date
(a date) as props, and describes a comment on a social media website.
由于所有的嵌套,这个组件可能会很难改变,并且很难重用它的各个部分。我们从中提取一些组件。
首先,我们将提取Avatar
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> ); }
继续提取UserInfo
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> ); }
1.5、Props是只读的
无论你是将一个组件声明为一个函数还是一个类,它都不能修改它自己的道具。考虑这个总和函数:
function sum(a, b) { return a + b; }
这些函数被称为“纯粹的”,因为它们不会尝试改变它们的输入,并且总是为相同的输入返回相同的结果。
相反,这个函数是不纯的,因为它改变了它自己的输入:
function withdraw(account, amount) { account.total -= amount; }
React非常灵活,但它有一个严格的规则:
All React components must act like pure functions with respect to their props.