【全棧React】第5天: 數據驅動

本文轉載自:衆成翻譯
譯者:iOSDevLog
連接:http://www.zcfy.cc/article/3821
原文:https://www.fullstackreact.com/30-days-of-react/day-5/javascript

咱們的應用程序中的硬編碼數據不是好主意。 今天,咱們將把咱們的組件設置爲由數據驅動,訪問外部數據。java

經過這一點,咱們已經編寫了咱們的第一個組件並將其設置爲子/父關係。可是,咱們尚未將任何數據綁定到咱們的React組件。雖然在React中寫一個網站是一個更愉快的體驗(在咱們看來),咱們尚未利用React的力量來顯示任何動態數據。react

今天咱們來改一下。api

數據驅動

回想一下,昨天咱們構建了包含頭和活動列表的時間軸組件的開始:數組

咱們將演示分解成組件,最終用靜態JSX模板構建了三個獨立的組件。每當咱們改變網站的數據時,不得不更新咱們組件的模板是不方便的。瀏覽器

而是讓咱們給出要使用的組件數據進行顯示。咱們從 <Header /> 組件開始吧。如今,<Header />組件只顯示元素的標題 Timeline。這是一個很好的元素,它將是很好的可以重用它在咱們的頁面的其餘部分,但標題是 Timeline 沒有意義的每一次使用。函數

讓咱們告訴React,咱們但願可以將標題設置爲別的東西。oop

介紹屬性

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 概念更新了由數據驅動的組件。在下一節中,咱們將介紹有狀態的組件。

相關文章
相關標籤/搜索