[译]React核心概念3:组件&props

原文连接:reactjs.org/docs/compon…html

引言

组件将UI划分红独立的,可复用的片断,并对每一个组件进行独立的构思。本节将会介绍组件的构建思路。react

概念上来讲,组件就好像是JavaScript里的函数。它们可以接受任意的入参(称做props)并返回描述屏幕展现UI的React元素。数组

函数组件&类组件

定义组件最简单的方法就是写一个JavaScript函数。bash

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

不用担忧,这是一个可以使用的组件,由于它接收了一个带有数据的props(也能够用properties代替)做为参数对象而且返回了一个React元素。咱们把这种组件成为函数组件(由于这就是一个函数)。网络

您也可使用ES6 class来定义组件。app

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
复制代码

上述两个组件从React的组件定义来看是等价的。函数

类组件还有一些特性咱们将会放到下一节讲解。在那以前咱们将使用函数组件来进行示例讲解。网站

渲染组件

以前咱们讲的都只是用React元素来表明DOM标签。ui

const element = <div />;
复制代码

然而,React元素也能够表示用户定义的组件。this

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. 咱们在调用ReactDOM.render()函数时将 <Welcome name="Sara" />做为参数传递给了它。
  2. React在调用Welcome组件时把{name:"Sara"}做为props传递给他。
  3. Welcome组件返回了<h1>Hello, Sara</h1>
  4. React Dom更新了DOM以匹配<h1>Hello, Sara</h1>

提示:定义组件时组件名要以大写字母开头 React将以小写字母开头的组件视为DOM标签,例如<div/>表示一个HTML的 div 标签。可是<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')
);
复制代码

当您使用create-react-app建立一个React应用时,您会发如今应用中App组件做为顶层组件被使用。可是若是您是在现有应用中整合React,那么您能够自底向上地从使用一个小组件开始,逐步地将React组件应用到您应用的各个层级上。

提取组件

不要惧怕将组件分解成更小的组件。

举个例子,让咱们观察下面的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(object),text(string),date(date)做为props,而且描述了社交网站上的一个评论。

因为这个组件嵌套了太多层的内容,而且其中的内容很难复用。因此,让咱们来从中提取组件吧。

首先,咱们来提取Avatar组件。

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}
复制代码

Avatar组件不须要知道它是否被渲染在Comment组件里,所以在这里咱们将它的prop起了一个更普适的名字user

咱们推荐在给prop起名时从组件的角度上考虑,而不是从使用组件的上下文的联想上考虑。

如今咱们在编写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组件来渲染带有名字的头像。

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中的一部分须要使用屡次(就像ButtonPanelAvatar),或者这个页面/组件自己很复杂时,那么您就能够把他提取成组件了。

Props是只读的

无论您是声明了一个函数组件仍是类组件,它的props是不能更改的。咱们来观察下面的代码。

function sum(a, b) {
  return a + b;
}
复制代码

这样的函数称为纯函数,由于它们不会改变它们的入参,而且在相同的入参下永远返回相同的结果。

相反,下面的函数就不是纯函数,由于它改变了它的入参。

function withdraw(account, amount) {
  account.total -= amount;
}
复制代码

React很是灵活,可是却有一个严格的规则:

全部的组件都必须想纯函数同样保护它们的props不被更改

不过,UI是动态的而且老是在改变,在下一节,咱们将会介绍一个新概念“状态(state)”。状态可让组件在不违反上述规则的状况下更具用户的动做或者网络传输结果改变输出。

相关文章
相关标签/搜索