zoukankan      html  css  js  c++  java
  • 【译】快速起步-组件与属性

    react version: 15.5.0

    组件与属性

    组件允许您将UI拆分为多个独立的,可重用的部分。

    概念上,组件就类似于 JavaScript 函数。它们接收任意的输入(props),返回用于描述屏幕显示内容的 React elements

    函数式组件和类组件

    最简单定义组件的方式,是编写一个 JavaScript 函数:

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

    这个函数是一个合法的组件,因为它接收包含数据的单个 props 对象参数,返回了一个 React elements。我们称这种用JavaScript函数定义的组件为函数式组件。

    你也可以使用 ES6 class 来定义组件:

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

    上述两个组件在视图展示上是等同的。

    下一章节 我们会讨论类组件的一些附加特性。在这之前,我们先使用函数式组件来简化演示。

    渲染组件

    之前,我们仅仅遇到表示DOM标签的 React elements

    const element = <div />;
    

    然而,元素也可以表示用户定义的组件:

    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')
    );
    

    CodePen Demo

    我们回顾下这个例子中发生了什么:

    1. 使用 <Welcome name="Sara" /> 元素调用 ReactDOM.render()
    2. React 将 {name: 'Sara'} 作为属性调用 Welcome 组件。
    3. Welcome 组件将 <h1>Hello, Sara</h1> 元素作为结果返回。
    4. React DOM 使用 <h1>Hello, Sara</h1> 来更新DOM。

    警告:

    总是用大写字母开头命名自定义组件

    例如, <div /> 表示一个DOM标签,但是 <Welcome /> 表示一个组件,且需要作用域中存在 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')
    );
    

    CodePen Demo

    通常,新的React应用程序在最顶层都会有一个 App 组件。然而,如果你集成 React 到一个现有的应用程序,你可以在内部先使用像 Button 这样的小部件,然后逐步的替换到最顶层。

    警告:

    组件必须返回单个根元素。这是为什么我们用 <div> 来包含多个 <Welcome /> 组件。

    提取组件

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

    例如,思考这个 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>
      );
    }
    

    CodePen Demo

    它接收 author(对象类型),text(字符串)和 date(日期) 作为属性,然后在社交网站上呈现一个评论。

    由于多层嵌套,这个组件很难变化,且很难重用它其中的各个部分。我们可以从中提取几个组件。

    首先,我们提取 Avatar 组件:

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

    Avatar 不需要知道谁会渲染它。这也是为什么我们使用 user 这个更通用的属性名称来替代 author

    我们建议从组件自身的角度来命名属性,而不是它的使用者。

    我们现在已经稍微简化了一下 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 组件,用于在用户名旁边显示 Avator

    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>
      );
    }
    

    CodePen Demo

    提取组件可能是看起来很繁琐的工作,但是在较大的应用程序中,可重用的组件能够付出更小的代价。
    如果您的UI的一部分使用了几次(按钮,面板,头像)或者它自身就很复杂(App, Comment),它们则是拆分出可重用组件的最佳候选人,这是一个相当实用的经验法则。

    属性是只读的

    当你定义一个组件时,它不应该修改自己的 props。思考下面的 sum 函数。

    function sum(a, b) {
      return a + b;
    }
    

    这些不会修改输入参数,且当输入参数相同时,总是返回相同结果的函数被称之为 纯函数

    相比之下,以下的函数是不纯的,因为它改变了自己的输入:

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

    React 非常灵活,但是也有一个严格的规则:

    所有的React组件必须像纯函数那样使用 props(也就是不要在组件内部修改 props

    当然,应用程序的UI是动态的,可以随时间的推移而变化。在 下一节 中,我们将介绍新的概念 statestate 允许React组件根据用户操作,网络响应以及其他随时间推移产生的变化来修改组件输出,而不会违背该规则。

  • 相关阅读:
    IP应用加速技术详解:如何提升动静混合站点的访问速率?
    阿里云PolarDB发布重大更新 支持Oracle等数据库一键迁移上云
    BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览
    洛谷P1457 城堡 The Castle
    洛谷P1461 海明码 Hamming Codes
    洛谷P1460 健康的荷斯坦奶牛 Healthy Holsteins
    洛谷P1459 三值的排序 Sorting a Three-Valued Sequence
    洛谷P1458 顺序的分数 Ordered Fractions
    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
    洛谷P1215 [USACO1.4]母亲的牛奶 Mother's Milk
  • 原文地址:https://www.cnblogs.com/humin/p/6710109.html
Copyright © 2011-2022 走看看