【全栈React】第5天: 数据驱动

本文转载自:众成翻译
译者:iOSDevLog
链接:http://www.zcfy.cc/article/3821
原文:https://www.fullstackreact.com/30-days-of-react/day-5/

我们的应用程序中的硬编码数据不是好主意。 本日,我们将把我们的组件设置为由数据驱动,接见外部数据。

经由过程这一点,我们已编写了我们的第一个组件并将其设置为子/父关联。然则,我们还没有将任何数据绑定到我们的React组件。虽然在React中写一个网站是一个更兴奋的体验(在我们看来),我们还没有应用React的气力来显现任何动态数据。

本日我们来改一下。

数据驱动

追念一下,昨天我们构建了包括头和运动列表的时候轴组件的最先:

我们将演示分解成组件,终究用静态JSX模板构建了三个自力的组件。每当我们转变网站的数据时,不能不更新我们组件的模板是不方便的。

而是让我们给出要运用的组件数据举行显现。我们从 <Header /> 组件最先吧。如今,<Header />组件只显现元素的题目 Timeline。这是一个很好的元素,它将是很好的能够重用它在我们的页面的其他部份,但题目是 Timeline 没有意义的每一次运用。

让我们通知React,我们愿望能够将题目设置为别的东西。

引见属性

React许可我们以与HTML雷同的语法向组件发送数据,运用组件上的特征或 属性。这类似于将 src 属性通报给图象标签。我们能够斟酌 <img /> 标签的属性,因为prop我们正在设置挪用的组件img。

我们能够接见组件内的这些属性 this.props。让我们看看在行动中运用 props

追念一下,我们将 <Header /> 组件定义为:

class Header extends React.Component {
  render() {
    return (
      <div className="header">
        <div className="menuIcon">
          <div className="dashTop"></div>
          <div className="dashBottom"></div>
          <div className="circle"></div>
        </div>

        <span className="title">
          {this.props.title}
        </span>

        <input
          type="text"
          className="searchInput"
          placeholder="Search ..." />

        <div className="fa fa-search searchIcon"></div>
      </div>
    )
  }
}

当我们运用该 <Header /> 组件时,我们将它放在我们的 <App /> 组件中:

<Header />

我们能够 title 作为一个属性通报我们作为一个属性,<Header /> 经由过程更新组件的运用设置挪用 title 某个字符串的属性,以下所示:

<Header title="Timeline" />

在我们的组件内部,我们能够 title 从课程中的 this.props 属性接见 Header。而不是像 Timeline 模板一样静态设置题目,我们能够将其替换为传入的属性。

import React from 'react'

class Header extends React.Component {
  render() {
    return (
      <div className="header">
        <div className="menuIcon">
          <div className="dashTop"></div>
          <div className="dashBottom"></div>
          <div className="circle"></div>
        </div>

        <span className="title">
          {this.props.title}
        </span>

        <input
          type="text"
          className="searchInput"
          placeholder="Search ..." />

        <div className="fa fa-search searchIcon"></div>
      </div>
    )
  }
}

export default Header

如今我们的 <Header /> 组件将显现我们传入的字符串,title 当我们挪用该组件时。比方,<Header /> 像如许挪用我们的组件四次:

<Header title="Timeline" />
<Header title="Profile" />
<Header title="Settings" />
<Header title="Chat" />

效果四个 <Header /> 组件加载完成后以下:

很漂亮,是吗?如今我们能够复用 <Header /> 组件, 运用一个动态 title 属性。

我们能够通报不仅仅是组件中的字符串。我们能够通报数字,字符串,种种对象,以至功用!我们将进一步议论怎样定义这些差别的属性,以便稍后构建组件api。

我们来看内容组件,并用数据变量而不是而不是静态设置内容和日期。就像我们能够运用HTML组件一样,我们能够将多个 props 组件通报给组件。

追念一下,昨天我们定义了我们的 Content 容器,以下所示:

class Content extends React.Component {
  render() {
    return (
      <div className="content">
        <div className="line"></div>

      {/* Timeline item */}
        <div className="item">
          <div className="avatar">
            <img src="http://p0.qhimg.com/t01e9226cd16ce24fb4.jpg" />
            Doug
          </div>

          <span className="time">
            An hour ago
          </span>
          <p>Ate lunch</p>
          <div className="commentCount">
            2
          </div>
        </div>

        {/* ... */}

      </div>
    )
  }
}

和我们 title 一样,我们来看看 props 我们的 Content 组件需求:

  • 用户的头像图片
  • 运动的时候戳
  • 运动项的笔墨
  • 批评数目

假定我们有一个代表运动项目的JavaScript对象。我们将有一些字段,如字符串字段(文本)和日期对象。我们能够会有一些嵌套的对象 usercomments。比方:

{
  timestamp: new Date().getTime(),
  text: "Ate lunch",
  user: {
    id: 1,
    name: 'Nate',
    avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
  },
  comments: [
    { from: 'Ari', text: 'Me too!' }
  ]
}

就像我们将一个字符串题目通报给 <Header /> 组件一样,我们能够把这个 activity 对象通报给 Content 组件。我们转换我们的组件来显现它的模板内的这个运动的细节。

为了将动态变量的值通报给一个模板,我们必需运用模板语法在我们的模板中显现。比方:

import React from 'react'

class Content extends React.Component {
  render() {
    const {activity} = this.props; // ES6 destructuring

    return (
      <div className="content">
        <div className="line"></div>

        {/* Timeline item */}
        <div className="item">
          <div className="avatar">
            <img
              alt={activity.text}
              src={activity.user.avatar} />
            {activity.user.name}
          </div>

          <span className="time">
            {activity.timestamp}
          </span>
          <p>{activity.text}</p>
          <div className="commentCount">
            {activity.comments.length}
          </div>
        </div>
      </div>
    )
  }
}

export default Content

我们在我们的类定义中运用了一点ES6,在第一行定义就是这个render() 的解构函数。以下两行在功用上相称:

// these lines do the same thing
const activity = this.props.activity;
const {activity} = this.props; 

解构使我们能够以更短,更紧凑的体式格局节约打字和定义变量。

然后,我们能够经由过程通报一个对象作为支撑而不是硬编码的字符串来_运用_这个新内容。比方:

<Content activity={moment1} />

太棒了,如今我们有一个由一个对象驱动的运动项。然则,您能够已注意到,我们将不能不运用差别的解释完成这个屡次。相反,我们能够将一组对象通报到组件中。

假定我们有一个包括多个运动项目的对象:

const activities = [
  {
    timestamp: new Date().getTime(),
    text: "Ate lunch",
    user: {
      id: 1, name: 'Nate',
      avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
    },
    comments: [{ from: 'Ari', text: 'Me too!' }]
  },
  {
    timestamp: new Date().getTime(),
    text: "Woke up early for a beautiful run",
    user: {
      id: 2, name: 'Ari',
      avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
    },
    comments: [{ from: 'Nate', text: 'I am so jealous' }]
  },
]

我们能够 <Content /> 经由过程通报多个运动来从新论述我们的运用,而不仅仅是一个:

<Content activities={activities} />

然则,假如我们革新视图什么都不会涌现!我们须要先更新我们的 Content 组件以接收多个运动。正如我们之前相识到的,JSX真的只是由浏览器实行的JavaScript。我们能够在JSX内容中实行JavaScript函数,因为它将像浏览器的JavaScript一样运转。

我们将我们的运动项目 JSX 挪动 map 到我们将针对每一个项目运转的项目中。

import React from 'react'

class Content extends React.Component {
  render() {
    const {activities} = this.props; // ES6 destructuring

    return (
      <div className="content">
        <div className="line"></div>

        {/* Timeline item */}
        {activities.map((activity) => {
          return (
            <div className="item">
              <div className="avatar">
                <img
                  alt={activity.text}
                  src={activity.user.avatar} />
                {activity.user.name}
              </div>

              <span className="time">
                {activity.timestamp}
              </span>
              <p>{activity.text}</p>
              <div className="commentCount">
                {activity.comments.length}
              </div>
            </div>
          );
        })}

      </div>
    )
  }
}

export default Content

如今我们能够将任何数目的运动通报给我们的数组,Content 组件将处置惩罚它,然则假如我们如今脱离组件,那末我们将有一个相对庞杂的组件处置惩罚,包括和显现运动列表。像如许脱离真的不是React的体式格局。

运动项

这里写一个组件包括显现单个运动项然后再竖立一个庞杂的 Content 组件是有意义的,我们能够挪动义务。这也将使测试更轻易,增加功用等

让我们更新我们的 Content 组件以显现组件列表 ActivityItem(我们将鄙人面建立)。

import React from 'react'

import ActivityItem from './ActivityItem';

class Content extends React.Component {
  render() {
    const {activities} = this.props; // ES6 destructuring

    return (
      <div className="content">
        <div className="line"></div>

        {/* Timeline item */}
        {activities.map((activity) => (
          <ActivityItem
            activity={activity} />
        ))}

      </div>
    )
  }
}

export default Content

这不仅仅是简朴易懂,而且使得这两个组件的测试更轻易。

运用我们新颖的 Content 组件,让我们建立 ActivityItem 组件。因为我们已为此建立了视图 ActivityItem,所以我们须要做的就是将它从我们 Content 组件的模板复制为本身的模块。

import React from 'react'

class ActivityItem extends React.Component {
  render() {
    const {activity} = this.props; // ES6 destructuring

    return (
      <div className="item">
        <div className="avatar">
          <img 
            alt={activity.text} 
            src={activity.user.avatar} />
          {activity.user.name}
        </div>

        <span className="time">
          {activity.timestamp}
        </span>
        <p>{activity.text}</p>
        <div className="commentCount">
          {activity.comments.length}
        </div>
      </div>
    )
  }
}

export default ActivityItem

本周,我们运用React props 观点更新了由数据驱动的组件。鄙人一节中,我们将引见有状况的组件。

    原文作者:二月红
    原文地址: https://segmentfault.com/a/1190000010470458
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞