React教程第18部分:处理TODO应用程序的第六阶段

在React教程的今天翻译的这一部分中,邀请您继续使用Todo应用程序,并确保单击标志会影响组件的状态。

图片

第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部分:课程项目

课33.讲习班。 TODO应用程序。 阶段数6


原创

▍工作


在本实践课程中,我们将继续使用Todo应用程序,并确保用户操作会影响组件的状态。 它使我们可以将待办事项列表上的项目标记为已完成或未完成。 以下是App组件的代码,其中一些可用的工件和注释旨在帮助您完成任务。 实际上,这是今天邀请您执行的操作:

  1. App组件中创建一个事件处理程序,以响应标志更改(我们正在谈论onChange事件)并相应地更改应用程序的状态。 也许这是今天任务中最困难的部分。 为了解决这个问题,请注意代码中的注释和空格。
  2. 将适当的方法传递给TodoItem组件。
  3. TodoItem组件中TodoItem创建一种机制,该机制在onChange事件onChange ,调用传递给组件实例的方法,并向其传递案例标识符( id ),该标识符对应于用户单击的标志。

这是App组件的代码:

 import React from "react" import TodoItem from "./TodoItem" import todosData from "./todosData" class App extends React.Component {   constructor() {       super()       this.state = {           todos: todosData       }       this.handleChange = this.handleChange.bind(this)   }     handleChange(id) {       //   ,      id        // completed   c false  true ( ).       //   ,       .       //       ,  .       // (  ,       map.)   }     render() {       const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item}/>)             return (           <div className="todo-list">               {todoItems}           </div>       )   } } export default App 

▍解决方案


首先,创建一个简单的机制来检查对handleChange()方法的调用。 即,我们将其转换为以下形式:

 handleChange(id) {   console.log("Changed", id) } 

现在,我们正在根据任务的第2和第3段执行需要执行的操作。 也就是说,我们将在单击该标志与通过将该标志的id传递给它的调用handleChange()方法之间创建连接。

为了handleChange()的引用传递给TodoItem组件的实例,我们可以像将属性传递给它一样,并重写用于创建组件列表的代码,如下所示:

 const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>) 

请注意, TodoItem组件可以使用的handleChange属性包含对App组件实例的handleChange方法的引用。 在TodoItem组件中,可以使用与传递给它的其他属性相同的方式来访问此方法。 在此阶段, TodoItem代码如下所示:

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

要在组件代码中调用handleChange方法,可以使用props.handleChange()形式的构造。 在这种情况下,此方法需要传递元素的idonChange事件onChange接受一个事件对象。 我们不需要此对象来调用handleChange()方法。 我们重写将onChange事件处理程序分配给元素的代码,如下所示:

 onChange={(event) => props.handleChange(props.item.id)} 

在这里,我们调用handleChange()方法,从另一个接受事件对象的函数中,将元素标识符(从传递给它的属性中获取)传递给它。 由于我们不在这里使用此对象,因此可以像下面这样重写代码:

 onChange={() => props.handleChange(props.item.id)} 

现在尝试运行该应用程序,然后打开控制台,单击复选框。


测试handleChange()方法

包含标记标识符的消息,我们通过单击这些标识符进入控制台。 但是这些标志尚未更改外观,因为handleChange()方法尚未实现更改组件状态的机制。 结果,我们只处理了任务的第二部分和第三部分,现在我们可以开始处理与国家合作有关的第一部分,这也许是最有趣的部分。

首先,我们需要解决关于数组存储在状态中的状态的问题,该数组的元素响应于单击标志而应进行更改,但我们不应该修改存储在该状态的旧版本中的数组。 也就是说,例如,您不能只是遍历状态中的对象数组,找到必要的元素并更改其completed属性。 我们需要在更改状态之后,形成一个新数组,其中一个元素将被更改,其余元素将保持与以前相同。 形成这种数组的方法之一是使用map()数组方法,该注释在任务注释中提到。 我们将在setState()方法中编写代码。 让我们handleChange() App组件中handleChange()方法handleChange()代码转换为以下形式:

 handleChange(id) {   this.setState(prevState => {         }) } 

现在,使用map()方法,我们将遍历prevState.todos数组,并在其中查找所需的元素,即将其id传递给handleChange()方法的handleChange() ,然后更改其completed属性。 map()方法返回一个新的数组,该数组将在应用程序的新状态中使用,因此我们将该数组写入常量。 看起来是这样的:

 handleChange(id) {   this.setState(prevState => {       const updatedTodos = prevState.todos.map(todo => {           if (todo.id === id) {               todo.completed = !todo.completed           }           return todo       })       return {           todos: updatedTodos       }   }) } 

在此,在使用map()处理数组的过程中,如果handleChange() id等于传递给handleChange()方法的id的元素,则该元素的completed属性的值将反转( truefalse ,反之亦然)。 之后,无论元素是否已更改, map()返回该元素。 它属于同一状态下的新数组( updatedTodos数组中由updatedTodos常量表示),该索引下相应元素位于该状态的先前版本的todos数组中。 在扫描了整个数组并完全形成了updatedTodos数组之后,该数组将用作setState()方法返回的对象的todos属性的值,该方法是该状态的新版本。

如果立即启动该应用程序,则可能会发现这些标志响应了我们的效果。 这表明单击它们会更改应用程序的状态,然后使用新数据重新呈现它们。

总结


今天,我们在编写时使用了一个工作的Todo应用程序,该应用程序使用了许多我们研究过的React概念。 实际上,仍然有可能对其进行改进,尤其是对其进行样式化和扩展其功能。 我们将在以下课程之一中返回他。

亲爱的读者们! 您应付今天的实际工作了吗?

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


All Articles