React教程第11部分:动态标记形成和映射数组方法

在React培训课程的今天翻译中,我们将讨论使用标准map()数组方法来组织JSX标记的动态形式,以描述同一类型的元素集。

图片

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

第21课。动态标记生成和映射数组方法


原创

从我们停止完成上一个实际任务的那一刻起,我们将继续工作。 回想一下, App.js文件的代码如下所示:

 import React from "react" import Joke from "./Joke" function App() {   return (       <div>           <Joke punchLine="It's hard to explain puns to kleptomaniacs because they always take things literally." />                     <Joke               question="What's the best thing about Switzerland?"               punchLine="I don't know, but the flag is a big plus!"           />                     <Joke               question="Did you hear about the mathematician who's afraid of negative numbers?"               punchLine="He'll stop at nothing to avoid them!"           />                     <Joke               question="Hear about the new restaurant called Karma?"               punchLine="There's no menu: You get what you deserve."           />                     <Joke               question="Did you hear about the actor who fell through the floorboards?"               punchLine="He was just going through a stage."           />                     <Joke               question="Did you hear about the claustrophobic astronaut?"               punchLine="He just needed a little space."           />                 </div>   ) } export default App 

App组件显示一组Joke组件。 这是应用程序页面在此工作阶段的外观。


申请页面

questionpunchLine属性将传递给其中一些组件,仅将punchLinepunchLine 。 这些属性的值现在在Joke组件实例化代码中以纯文本设置。 实际上,React应用程序页面上显示的大量数据是由于对某些API的HTTP请求而进入应用程序的。 服务器通过以下方式支持这些API:这些服务器从数据库中获取信息,以JSON代码的形式对其进行格式化,然后将此代码发送至应用程序的客户端。 我们尚未达到满足API请求的水平,因此,现在,作为数据源,我们将使用一个文件,该文件中的数据可以通过解析服务器的JSON响应来获取。 即,它将是一个具有以下内容的jokesData.js文件:

 const jokesData = [   {       id: 1,       punchLine: "It's hard to explain puns to kleptomaniacs because they always take things literally."   },   {       id: 2,       question: "What's the best thing about Switzerland?",       punchLine: "I don't know, but the flag is a big plus!"   },   {       id: 3,       question: "Did you hear about the mathematician who's afraid of negative numbers?",       punchLine: "He'll stop at nothing to avoid them!"   },   {       id: 4,       question: "Hear about the new restaurant called Karma?",       punchLine: "There's no menu: You get what you deserve."   },   {       id: 5,       question: "Did you hear about the actor who fell through the floorboards?",       punchLine: "He was just going through a stage."   },   {       id: 6,       question: "Did you hear about the claustrophobic astronaut?",       punchLine: "He just needed a little space."   } ] export default jokesData 

该文件将位于我们项目的src目录中。


src文件夹中的新文件

实际上,它包含一个对象数组。 通过解析从某个API接收到的JSON数据可以获得类似的数组。 我们从该文件中导出一个jokesData数组。 如有必要,我们可以将该文件导入到需要它的组件中,并想象我们不是在处理从文件中获取的数据,而是使用返回了某些API的数据。

现在我们有了一个源数据数组,让我们考虑如何将这些数据转换为一组React组件实例。

许多开发人员说,由于精通React,他们对JavaScript有了更多的了解。 这样做的原因是因为类似于Angular和Vue等其他框架中将要讨论的动作是使用某些特殊方式执行的。 在React中,这是使用常规JavaScript来完成的。

特别是,我们计划使用一些标准的数组方法,这些方法是高阶函数。 这些方法可以接受程序员描述的功能作为参数。 正是这些函数确定了对一个或另一个标准方法的调用将如何处理数组的元素。

假设我们有一个数值数组:

 const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

我们可以使用标准map()数组方法处理该数组,并向其传递某个函数,该函数设置该数组元素的转换顺序。 在我们的例子中,此函数将一次传递该数组中的数字。 函数可以对它们执行任何操作,然后返回的结果将进入新数组,并返回到元素的索引与要处理的元素的索引对应的元素。 如果我们需要形成一个新数组,其元素是原始数组的元素乘以2,那么它将看起来像这样:

 const doubled = nums.map(function(num) {   return num * 2 }) 

检查此代码的操作:

 console.log(doubled) // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 

如果您之前还没有遇到过数组方法 (例如map()filter()reduce()reduce() ,建议您处理它们。

在这里,我们将使用map()方法自动生成组件实例列表。

让我们回到我们的例子。 将App.js文件导入App.js文件。 这样做是这样的:

 import jokesData from "./jokesData" 

之后,在程序代码中,我们可以使用jokesData数组。 即,我们将使用map()方法。 这是此方法的“空白”外观。

 jokesData.map(joke => { }) 

请注意,这里我们将arrow函数传递给map()方法。 就我们而言,这使我们可以使代码更紧凑。 由于该函数仅接受一个参数( joke ),因此在声明该函数时,可以不加括号。

从传递给map()方法的函数中,我们想返回一个Joke组件的新实例,并将punchLine其中的punchLine数组元素的questionpunchLine属性punchLine给该实例。 可能是这样的:

 jokesData.map(joke => {   return (   <Joke question={joke.question} punchLine={joke.punchLine} />   ) }) 

如果考虑到两个事实,可以缩短此代码。 首先, return仅返回一个元素,因此您可以在return之后立即放置此元素,而无需括号。 其次,箭头函数仅包含返回某个值的操作,因此,在声明该函数时,可以不用return关键字和花括号。 此外,我们还记得作为map()方法的结果,形成了一个新的数组。 该阵列需要保存在某个地方。 所有这些考虑因素使我们得出以下几点:

 const jokeComponents = jokesData.map(joke => <Joke question={joke.question} punchLine={joke.punchLine} />) 

现在, jokeComponents常量jokeComponents包含一个数组,该数组的每个元素都是对Joke组件实例的描述,并将questionpunchLine属性传递给该实例。

现在,我们如何使用这一系列组件? React使使用这样的数组变得非常方便。 即,我们正在谈论这样的事实,即这样的数组可以在JSX代码中使用。 这是App文件代码现在的样子:

 import React from "react" import Joke from "./Joke" import jokesData from "./jokesData" function App() {   const jokeComponents = jokesData.map(joke => <Joke question={joke.question} punchLine={joke.punchLine} />)       return (       <div>           {jokeComponents}       </div>   ) } export default App 

之后,该应用程序页面将与以前相同,但是,您将在浏览器控制台中看到以下警告:

 Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `App`. See https://fb.me/react-warning-keys for more information.   in Joke (at App.js:7)   in App (at src/index.js:6) 

其含义归结为以下事实:数组元素必须具有唯一的key属性。 我们不会详细说明React为什么期望重复组件具有唯一key属性。 我们足够考虑以下事实,即在执行组件实例的批量创建时(例如我们刚刚使用map()方法执行的实例map() ,实例需要传递key属性。 而且,可以将这样的属性传递给组件实例本身,例如,传递给<div> ,该<div>中包含了组件代码。 这没有特殊作用。

因此,需要为key属性分配一些唯一值。 通常,在从API接收的数据对象中,有一些标识符(诸如id属性)。 对我们来说,最主要的是它们的独特性。 例如,我们可以将key属性设置为joke.question这些属性中的所有文本在我们的应用程序中都是唯一的。 但是我们会做其他事情。 请记住,从jokesData.js文件导出的jokesData.js数组数据的对象的jokesData.js 。 这是其中的一部分:

 const jokesData = [   {       id: 1,       punchLine: "It's hard to explain puns to kleptomaniacs because they always take things literally."   },   {       id: 2,       question: "What's the best thing about Switzerland?",       punchLine: "I don't know, but the flag is a big plus!"   }, ... ] 

每个对象都有一个id属性,我们将独立维护其唯一性。 可以将这些属性的值用作key属性的值。

现在,用于在App.js创建组件实例数组的代码将采用以下形式:

 const jokeComponents = jokesData.map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />) 

如果您在代码中进行了更改,请在浏览器中查看应用程序页面并检查控制台的内容,结果发现有关key属性的通知已消失。

在完成所有转换之后,我们对项目进行了处理,应用程序页面的外观未更改。 但是, App组件的代码变得更短,更清晰,并且用于构成组件列表的数据现在取自与外部数据源极为相似的内容。 真正的应用程序就是通过这种方式工作的。

另外,应该注意的是,上述代码修改的核心是使用标准map()数组方法。 我们使用了在App组件中创建Joke组件的实例列表的技术,但是没有必要阻止我们在Joke组件中使用相同的方法,该方法可以根据传输给它的数据创建自己的某个组件的实例列表。

同时,正如我们已经说过的,在数组的标准方法中,您可以找到其他有趣的工具。 例如, sort()方法可用于按某些属性对数组元素进行排序。 filter()方法只能用于选择满足某些条件的那些数组元素。 所有这些都适用于处理包含组件实例的数组。

如果需要,可以尝试使用这些方法。 假设尝试使用filter()方法,并从App组件生成的输出中删除那些question属性未超过指定长度的Joke组件实例。 或确保仅同时设置了question属性和punchLine属性的punchLine

总结


今天,我们讨论了使用标准map()数组方法编译组件列表,并讨论了其他标准数组方法为我们提供的可能性。 下次,您将获得关于今天所学习材料的实用课程。

亲爱的读者们! 您将如何解决由App组件仅显示问题属性超过指定长度的Joke组件实例的问题?

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


All Articles