React教程,第22部分:在TODO应用程序上工作的第七阶段,从外部源下载数据

在React教程的今天翻译的这一部分中,我们将完成Todo应用程序的工作,并讨论如何使用内部组件中的数据以及标准JavaScript功能从外部源中加载数据。

图片

第1部分:课程概述,React,ReactDOM和JSX普及的原因
第2部分:功能组件
第3部分:组件文件,项目结构
第4部分:父级和子级组件
第5部分:TODO应用程序的开始工作,样式设计的基础
第6部分:关于本课程的一些功能,JSX和JavaScript
第7部分:内联样式
第8部分:继续研究TODO应用程序,熟悉组件的属性
第9部分:组件属性
第10部分:使用组件特性和样式的研讨会
第11部分:动态标记生成和映射数组方法
第12部分:研讨会,TODO应用程序的第三阶段工作
第13部分:基于类的组件
第14部分:关于基于类的组件,组件状态的研讨会
第15部分:组件健康研讨会
第16部分:TODO应用程序的第四阶段工作,事件处理
第17部分:TODO应用程序的第五阶段工作,修改组件的状态
第18部分:TODO应用程序的第六阶段工作
第19部分:组件生命周期方法
第20部分:条件渲染的第一课
第21部分:关于条件渲染的第二课​​和研讨会
第22部分:TODO应用程序的第七阶段工作,从外部资源下载数据
第23部分:关于使用表格的第一课
第24部分:第二形式课
第25部分:使用表单的研讨会
第26部分:应用程序体系结构,容器/组件模式
第27部分:课程项目

课39.讲习班。 TODO应用程序。 阶段数7


原创

▍工作


现在,Todo应用程序如下图所示。


浏览器中的应用程序页面

TodoItem组件TodoItem如下所示:

 import React from "react" function TodoItem(props) {   return (       <div className="todo-item">           <input               type="checkbox"               checked={props.item.completed}               onChange={() => props.handleChange(props.item.id)}           />           <p>{props.item.text}</p>       </div>   ) } export default TodoItem 

您的任务是根据列表项目的状态设置样式。 完成的案例的外观应与不完整的外观不同。 在格式化代表已完成任务的列表项时,其文本可以变灰,可以被划线,斜体或可以进行其他修改。

▍解决方案


此处提出的问题可以通过多种方式解决。 我们将使用内置样式,在TodoItem功能组件的代码中将其描述为completedStyle常量。 在这里,我们配置文本属性fontStylecolortextDecoration 。 之后,使用条件渲染技术,如果由他推断的业务被标记为已完成,我们将为<p>元素分配此样式。 我们将基于传递给组件实例的属性来确定它,该属性可以在props.item.completed

转换后的组件代码将如下所示:

 import React from "react" function TodoItem(props) {   const completedStyle = {       fontStyle: "italic",       color: "#cdcdcd",       textDecoration: "line-through"   }     return (       <div className="todo-item">           <input               type="checkbox"               checked={props.item.completed}               onChange={() => props.handleChange(props.item.id)}           />           <p style={props.item.completed ? completedStyle: null}>{props.item.text}</p>       </div>   ) } export default TodoItem 

这是应用程序页面外观的变化方式。


在浏览器中更改了应用程序页面

同时,在设置和取消选中待办事项列表中指示项目状态的标志时,将应用样式。

到此结束有关Todo应用程序的工作。

课40.从外部源下载数据


原创

在有关组件生命周期方法的课程中,我们讨论了componentDidMount()方法。 尝试记住它是如何工作的。 通过此方法,可以在将组件添加到DOM树之后立即执行一些代码来干扰组件的操作。 当我们谈论组件生命周期方法时,我提到componentDidMount()方法最常用于从某些外部源加载数据。 组件使用此数据来实现其目的。

让我们以使用create-react-app App.js创建的新项目开始今天的实验,该项目的App.js文件包含以下代码:

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {}   }         render() {       return (           <div>               Code goes here           </div>       )   } } export default App 

在基于组件的App组件的代码中,我们描述了componentDidMount()方法,并通过从此方法向控制台输出内容来检查所得构造的可操作性。

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {}   }     componentDidMount() {       console.log("Hi!")   }     render() {       return (           <div>               Code goes here           </div>       )   } } export default App 

输出到控制台字符串Hi! 证明了代码的功能,因此我们可以继续工作。 如前所述,该方法通常会加载组件工作所需的数据。

在本课程中,我们将使用几种辅助工具,这些工具在将数据加载到组件中时对我们很有用。

第一个是内置的JavaScript功能。 我们正在谈论API Fetch ,这是一个方便的接口,用于基于promises获取资源,该接口允许您执行HTTP请求,并通过该请求加载数据。

我们将使用的第二个工具是Star Wars API 。 这个项目很好,因为它可以在前端应用程序中使用而没有任何特殊困难(特别是我们在谈论CORS配置功能)。

componentDidMount()方法中,我们将使用fetch()函数,向其传递用于加载数据的地址,将此数据转换为所需的类型,然后为了检查系统的正确操作,将此数据输出到控制台。 我们将方法代码转换为以下形式:

 componentDidMount() {   fetch("https://swapi.co/api/people/1")       .then(response => response.json())       .then(data => console.log(data)) } 

在这里,我们参考API下载有关电影中某个英雄的数据,然后将来自服务器的内容转换为JSON格式,然后将此数据打印到控制台。 下图中显示了进入控制台的内容。


从“星球大战” API下载的数据输出到控制台

如您所见,带有Luke Skywalker数据的对象进入控制台。 现在,在获得数据之后,我们需要考虑如何在应用程序页面上显示它们。 为了解决此问题,您首先应考虑以下事实:从外部下载的数据(如果未保存在任何地方)将无法在浏览器的应用程序页面上显示。 用于存储此类数据的位置是组件的状态。 将一个由空对象表示的新属性character添加到组件状态:

 this.state = {   character: {} } 

我们将在该属性中存储一个带有字符描述的对象,有关该对象的数据是从外部源下载的。 它们作为对象存在,因此在初始化状态时,将character属性设为空对象。

之后,在componentDidMount()方法代码的位置(获取数据的位置),我们将使用setState()方法将其写入状态。 而且,在这种情况下,之前在状态中存储的内容对我们不感兴趣,因此,我们可以简单地将包含状态的新表示形式的对象传递给此方法。 结果,我们来到了这个componentDidMount()方法代码:

 componentDidMount() {   fetch("https://swapi.co/api/people/1")       .then(response => response.json())       .then(data => {           this.setState({               character: data           })       }) } 

为了检查代码中现在存在的机制的正确操作,我们将在render()方法中显示在将加载的数据写入状态后必须存在于状态中的某些内容。 现在, App.js文件的代码将如下所示:

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           character: {}       }   }     componentDidMount() {       fetch("https://swapi.co/api/people/1")           .then(response => response.json())           .then(data => {               this.setState({                   character: data               })           })   }     render() {       return (           <div>               {this.state.character.name}           </div>       )   } } export default App 

这是应用程序页面在浏览器中的外观。


浏览器中的应用程序页面

在页面上显示Luke Skywalker文本演示了数据加载机制的工作方式。

我们的应用程序使用一个简单的请求,作为响应,该应用程序接收到少量数据,这些数据被快速处理并显示在页面上。 完成所有这些动作只需很少的时间。 因此,数据在屏幕上的显示速度如此之快,以至于我们得到的印象是,组件在屏幕上显示之后立即就已经包含了它。 但是,如果使用非常慢的通信线路访问远程数据源,或者从中缓慢加载数据的API响应请求,则应用程序可能需要很长时间才能在屏幕上显示此数据。 。 所有这些时间,屏幕将保持空白。 如果在实际应用程序中发生这种情况,则会使他们的用户感到困惑,他们可能会认为此类应用程序无法正常运行。 为了预期类似的情况,在数据的加载和处理期间,有必要向用户显示相应的消息。 这不适用于我们今天的主题,但是在这里进行讨论是适当的。

在实际的应用程序中,要警告用户他需要等待某些操作(例如下载数据),他们使用诸如加载指示器之类的东西。 就我们而言,在数据上传并准备好在页面上显示之前,我们将仅显示文本loading... 通过这样做,我们将能够评估应用程序状态中的数据存储给我们带来的可能性。

向状态添加一个新属性,指示是否在某个时间点正在加载数据。 调用loading并将其初始化为false 。 之后,在使用fetch()加载数据之前,我们将true写入此属性。

接下来,在render()方法中,基于loading状态属性,我们将配置页面上显示的文本。 经过这些转换后, App.js代码如下所示。

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           loading: false,           character: {}       }   }     componentDidMount() {       this.setState({loading: true})       fetch("https://swapi.co/api/people/1")           .then(response => response.json())           .then(data => {               this.setState({                   character: data               })           })   }     render() {       const text = this.state.loading ? "loading..." : this.state.character.name       return (           <div>               <p>{text}</p>           </div>       )   } } export default App 

但是,此代码无法正常工作。 即,这就是应用程序页面现在的样子。


浏览器中的应用程序页面

假定仅当从外部源下载数据时才在其上显示题词loading... ,但现在看来它一直在页面上显示。 在进一步阅读之前,请尝试查找并更正代码中的错误。

实际上,这里的问题在于,在开始数据加载之前,我们将loading设置为true ,而在下载完成之后,我们没有向false loading false 。 结果,文本loading...始终显示在页面上。 修复此错误并不难。 足够在我们将加载的数据写入状态的位置,将loading设置为false 。 结果, App.js代码App.js采用以下形式:

 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           loading: false,           character: {}       }   }     componentDidMount() {       this.setState({loading: true})       fetch("https://swapi.co/api/people/1")           .then(response => response.json())           .then(data => {               this.setState({                   loading: false,                   character: data               })           })   }     render() {       const text = this.state.loading ? "loading..." : this.state.character.name       return (           <div>               <p>{text}</p>           </div>       )   } } export default App 

现在,在加载数据时,会短暂显示题名“ loading... ”,然后在页面上显示角色的名称。

总结


在本课程中,您完成了Todo应用程序上的工作,并学习了如何使用componentDidMount()生命周期方法和标准的Fetch API从外部源加载数据,进行处理并将其显示在页面上。 另外,这里我们讨论了一种机制的实现,该机制用于通知用户有关应用程序正在执行的操作,这可能会花费很多时间。 下次我们将讨论表格。

亲爱的读者们! 您如何将数据从外部源加载到React应用程序中?

Source: https://habr.com/ru/post/zh-CN443212/


All Articles