Reactjs入门官方文档(三)【components-and-props】

来源:互联网 发布:车铣复合手工编程例子 编辑:程序博客网 时间:2024/05/29 01:52

Components and Props

译自reactjs官方文档

Components帮助把UI分割成独立的,可重用的片段, 而我们只需要孤立的考虑每个片段.
在概念上, components就像javascript的函数, 它们接受任意的输入(称为props), 然后返回描述UI的React Elements

Components的函数式表达和类表达

定义一个component最简单的办法是通过javascript函数:

function Welcome(props) {  return <h1>Hello, {props.name}</h1>;}

这个函数是一个有效的React component, 它接受一个单属性对象作为参数然后返回一个React element. 我们称这种对象是函数式的,因为他们字面上是javascript函数.

你也可以用ES6 class定义一个component:
“`javascript
class Welcome extends React.Component {
render() {
return

Hello, {this.props.name}

;
}
}

上面两种表达在React看来是相等的Classes有些其它功能将在下一节讨论, 在这之前我们使用简洁的函数式component.### 渲染一个Component在此之前我们只遇到过代表DOM元素的React elements:```javascriptconst element = <div />;<div class="se-preview-section-delimiter"></div>

不过,elements也能表达用户自定义对象

const element = <Welcome name="Sara" />;<div class="se-preview-section-delimiter"></div>

当React发现某个element代表了一个用户自定义component, 它将使用一个对象打包jsx属性传递给component, 我们称之为”props”

下面的例子将会在页面渲染”Hello Sara”:

function Welcome(props) {  return <h1>Hello, {props.name}</h1>;}const element = <Welcome name="Sara" />;ReactDOM.render(  element,  document.getElementById('root'));<div class="se-preview-section-delimiter"></div>

我们回顾下这个例子里发生了什么:
1. 调用ReactDOM.render()渲染<Welcome name="Sara" />element.
2. React将{name: 'Sara'}作为props调用Weclome component.
3. Weclome component返回<h1>Hello, Sara</h1>element作为结果.
4. React 及时有效的更新DOM以匹配<h1>Hello, Sara</h1>.

警告:
component首字母大写.
例如,<div />代表一个DOM元素, 但<Welcom />代表一个component, 而且要求Welcome component在可见的定义域内.

复合Components

Components可以在他们的输出中引用其它的components, 这可以使我们在任何维度的抽象上使用同一个component. 按钮,表单,对话框: 在react应用中, 所有这些都使用components表达.

例如, 我们创建一个App component, 它简单的多次渲染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'));<div class="se-preview-section-delimiter"></div>

通常新的React应用只在最顶端有一个App component. 但如果你尝试在一个已存在的应用中引入React, 你可能会自下而上的从类似按钮这种小的component开始,逐渐按照你的方式完成集成.

警告:
Components必须返回一个单根元素, 所以在上面的例子中用一个div包裹了所有的<Welcome />elements.

抽象出Components

不要害怕把components拆分成更小的components.
比如下面这个Comment component:

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>  );}<div class="se-preview-section-delimiter"></div>

它接受一个author对象,一个text字符串和date日期作为props,然后描述了社交网站上的一个评论.

这个component因为这些相互嵌套而难于修改, 而且难以复用其中某个部分, 让我们从中抽取出一些components.

首先是Avatar(头像):

function Avatar(props) {  return (    <img className="Avatar"      src={props.user.avatarUrl}      alt={props.user.name}    />  );}<div class="se-preview-section-delimiter"></div>

这个Avata不需要知道它将被渲染到Comment. 这也是我们为什么给他的props一个更抽象的名字:user而不是author.
建议在props命名时站在components的视角而不是它将被用到的上下文的视角进行.
现在我们可以将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>  );}<div class="se-preview-section-delimiter"></div>

接下来我们抽象出UserInfo component, 它包含一个Avata和用户名字:

function UserInfo(props) {  return (    <div className="UserInfo">      <Avatar user={props.user} />      <div className="UserInfo-name">        {props.user.name}      </div>    </div>  );}<div class="se-preview-section-delimiter"></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>  );}<div class="se-preview-section-delimiter"></div>

拆分出components的工作最初可能看起来有些繁琐, 但拥有一众可重用的components会使你在一个稍大的应用中游刃有余.
一条好的操作实践是,如果你UI的某个部分将被用到好多次,或者足够复杂, 使用可重用的component将是非常好的选择.

Props 是只读的

无论你使用函数式声明或者类声明一个component, 修改它的props都是禁止的.
试看下面的加和函数:

function sum(a, b) {  return a + b;}<div class="se-preview-section-delimiter"></div>

这种函数被称为无副作用的(pure),对应的impure函数:

function withdraw(account, amount) {  account.total -= amount;}

React相当灵活但有一条严格的规则:
* 所有的React components必须是无副作用的, 即不可以修改传入的props对象. *

当然,应用的UI是动态的, 在下一节将引入一个新的概念”state”. State允许components在不违反这条规则的情况下返回不同的element以响应用户动作,网络变化等.

原创粉丝点击