本文转载自:众成翻译
译者: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对象。咱们将有一些字段,如字符串字段(文本)和日期对象。咱们可能会有一些嵌套的对象 user
和 comments
。例如:
{ 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
概念更新了由数据驱动的组件。在下一节中,咱们将介绍有状态的组件。