本文转载自:众成翻译
译者:iOSDevLog
链接:http://www.zcfy.cc/article/3826
原文:https://www.fullstackreact.com/30-days-of-react/day-13/

今天,我们将通过如何显示多个组件来准备将外部数据引入我们的应用。

我们已经构建了一个没有任何外部数据的基本应用。在我们实现之前 (我们将在明天开始这个功能), 让我们来看看过去两周中我们所掩盖的事情:

重复元素

我们已经看到了这之前, 我们已经遍历了一个对象列表, 并在屏幕上呈现多个组件。在我们的应用中添加太多的复杂度来加载外部数据之前, 今天我们将快速了解如何在应用中重复组件/元素。

由于 jsx 被浏览器视为纯 javascript 的, 我们可以使用任何 传统 javascript 内的模板标签中的 jsx。我们已经看到了这一行动。作为一个快速演示:

const App = (props) => {return (<ul>{a.map(i => {return <li>{i}</li>})}</ul>)
}

注意模板标签{} 内的内容看起来简单的 javascript。那是因为它 只是 javascript。此功能允许我们使用 (大多数) 的 javascript 在我们的模板标签 包括 原生迭代器, 如 mapforEach

让我们来看看这是什么意思。让我们将上一个示例的 a 值从单个整数转换为整数列表:

const a = [1, 10, 100, 1000, 10000];

我们可以将 a 变量映射到我们的组件中, 并返回将为我们构建虚拟 DOM 的响应组件列表。

const App = (props) => {return (<ul>{a.map(i => {return <li>{i}</li>})}</ul>)
}

什么是map() 函数?

map() 函数是数组中一个原生javascript内置函数的。
它接受在数组的每个元素上运行的函数, 因此, 上面的函数将运行四次, 其值为i 开始为1 , 然后它将再次运行它的第二个值, i将被设置为10 等等等等。

让我们更新我们在第12天创建的应用与我们的 App 组件在这里。让我们打开我们的src/App.js 文件, 并将 App 组件的内容替换为此源。清理一些未使用的变量和您的src/App.js应该类似于以下内容:

import React from 'react';const a = [1, 10, 100, 1000, 10000];
const App = (props) => {return (<ul>{a.map(i => {return <li>{i}</li>})}</ul>)
}export default App

使用create-react-app命令生成的命令再次启动应用:npm start, 我们可以看到应用在浏览器中工作!

但是, 如果我们打开开发人员控制台, 我们将看到打印出错误。此错误是由以下事实引起的: React不知道如何跟踪我们列表中的各个组件, 因为它们只是看起来像一个 <li />组件。

出于性能原因, React使用虚拟 DOM 尝试限制在重新视图时需要更新的 DOM 元素的数量。如果没有任何变化, React不会使浏览器更新任何东西以节省工作。

此功能非常适合于构建 web 应用, 但有时我们必须通过为节点提供唯一标识符来帮助做出React。在映射列表和渲染组件是其中之一。

React要求我们通过使用特殊属性来识别惟一的组件, 这是列表中每个元素的 key 属性。key 属性可以是任何我们想要的, 但它 必须是唯一的 的元素。在我们的示例中, 我们可以在 map 中使用i变量, 因为数组中没有其他元素具有相同的值。

让我们更新映射来设置key:

const App = (props) => {return (<ul>{a.map(i => {return <li key={i}>{i}</li>})}</ul>)
}

子组件

我们在本周早些时候谈到了建立父子关系的事情, 但是让我们更详细地介绍一下如何访问父组件中的子组件, 以及如何呈现它们。

在第11天, 我们构建了一个 <Formatter />组件来处理时钟组件中的日期格式, 以使用户能够灵活地使用自己的自定义时钟渲染。回想一下, 我们所创建的实现实际上是相当丑陋和相对复杂的。

const Formatter = (props) => {let children = props.format.split('').map((e, idx) => {if (e === 'h') {return <Hour key={idx} {...props} />} else if (e === 'm') {return <Minute key={idx} {...props} />} else if (e === 's') {return <Second key={idx} {...props} />} else if (e === 'p') {return <Ampm key={idx} {...props} />} else if (e === ' ') {return <span key={idx}> </span>;} else {return <Separator key={idx} {...props} />}});return <span>{children}</span>;
}

我们可以用React.Children 对象来映射一个React对象的列表, 并让React做这个自举。其结果是一个更干净的 Formatter组件 (不是完美的, 但可使用的):

const Formatter = ({format, state}) => {let children = format.split('').map(e => {if (e == 'h') {return <Hour />} else if (e == 'm') {return <Minute />} else if (e == 's') {return <Second />} else if (e == 'p') {return <Ampm />} else if (e == ' ') {return <span> </span>;} else {return <Separator />}});return (<span>{React.Children.map(children, c => React.cloneElement(c, state))}</span>)
}

React.cloneElement

我们还没有谈论React.cloneElement() 函数, 所以让我们简单地看看它。
记得 WWWWWAAAAAYYYYY(way) 回到第2天, 我们看了如何浏览器 看待 JSX? 它把它变成了类似于如下的 javascript:

React.createElement("div", null, React.createElement("img", {src: "profile.jpg", alt: "Profile photo"}),React.createElement("h1", null, "Welcome back Ari")
); 

React.cloneElement() 为我们处理这个。有时我们会想复制它或添加自定义props/children的组件,而不是创建一个新的组件实例 (如果我们已经有一个)。所以我们可以保留它创建的相同的属性。我们可以用React.cloneElement() 来为我们处理这一切。

React.cloneElement()React.createElement() 函数有相同的api,参数所在的位置:

  1. 我们要克隆的 ReactElement
  2. 我们要添加到实例中的任何 props
  3. 我们希望它有任何children

在我们的 Formatter 示例中, 我们正在创建列表中所有子级 (<Hour />, <Minute />等组件) 并将state 对象作为其属性。

React.Children 的对象提供了一些很好的实用工具来处理children的函数。上面的 Formatter 示例使用 map 函数循环访问子级, 并在列表中克隆每一个。它为每一个创建一个key (如果需要), 使我们不必自己管理唯一性。

让我们使用React.Children.map() 函数更新我们的应用组件:

const App = (props) => {return (<ul>{React.Children.map(a, i => <li>{i}</li>)}</ul>)
}

在浏览器中, 一切仍然正常。

React.Children 中还有其他一些非常有用的方法,我们将主要使用React.Children.map() 函数,但了解其他可用的 对我们来说也是很好的。 点击文档 查看更多列表。

通过这一点, 我们只处理了本地数据, 而不是真正关注远程数据 (尽管我们在构建活动提要组件时 已经 简要地提到了它)。明天, 我们将进入与服务器的互动, 所以我们可以使用它在我们的React应用。

今天的工作很棒!

【全栈React】第13天: 重复元素相关推荐

  1. Python全栈工程师-第13周-韦玮-专题视频课程

    Python全栈工程师-第13周-71人已学习 课程介绍         Python全栈工程师 课程收益     培养Python全栈工程师 讲师介绍     韦玮 更多讲师课程     企业家,I ...

  2. gql怎么写_全栈 React + GraphQL 教程(一)

    Par友,记基开前不接些前家我告对猿果水使钮控t 1--前端:使用 Apollo 声明式地请求和 m朋支不器几事为的时后级功发发来久都这样含制层是请些间例业多在上屏屏有到随ock 数据 GraphQL ...

  3. 【全栈React】第6天: 状态

    本文转载自:众成翻译 译者:iOSDevLog 链接:http://www.zcfy.cc/article/3824 原文:https://www.fullstackreact.com/30-days ...

  4. Python全栈-magedu-2018-笔记13

    第六章 - Python解析式.生成器 解析式.生成器 应该算是python特有的.用熟需要练习,可以大大简化写的代码的长度,原来写好几行,现在写一行就行了. 标准库datetime datetime ...

  5. 减治求有重复元素的全排列

    求n个元素的全排列的所有解可以用减治法:每次拎出一个数做前缀,对剩下的元素再求全排列,直至只剩一个元素.代码源自<算法分析与设计(王晓东)>,复杂度O(n!) 1 //输出k~m的所有全排 ...

  6. 前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)持续更新

    文档描述 本文是关注微信小程序的开发和面试问题, 由基础到困难循序渐进, 适合面试和开发小程序. 并有热点框架(vue react node.js 全栈)前端资源以及后端视频资源和源码 并基于前端进阶 ...

  7. 2020前端最新面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)(3年前端菜鸟级开发师含泪总结)

    2020前端最新面试题总结(js.html.小程序.React.ES6.Vue.算法.全栈热门视频资源) 文档描述 (今年确实挺难 3年前端菜鸟级开发师含泪总结 希望能帮助大家) 本文是关注微信小程序 ...

  8. 前端面试题总结(js、html、小程序、React、ES6、Vue、全栈)

    前端面试题总结(js.html.小程序.React.ES6.Vue.全栈) 文档描述 本文是关注微信小程序的开发和面试问题, 由基础到困难循序渐进, 适合面试和开发小程序. 并有热点框架(vue re ...

  9. 前端面试题精编2020(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)持续更新

    文档描述 本文是关注微信小程序的开发和面试问题, 由基础到困难循序渐进, 适合面试和开发小程序. 并有热点框架(vue react node.js 全栈)前端资源以及后端视频资源和源码 并基于前端进阶 ...

最新文章

  1. linux sa 命令,Linux 常用命令全拼
  2. 【工具使用系列】关于 MATLAB 电路与系统分析,你需要知道的事
  3. Linux的Nginx七:对比|模块
  4. 物联网有哪些技术 物联网跟云计算人工智能有什么关系
  5. ubuntu下wps不能输入中文
  6. 【英语学习】4000 Words 【V1】【U01】The Lion and the Rabbit
  7. C#无法生成解决方案,System.InvalidOperationException: 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分。
  8. 我靠! 算你运气好 a joke
  9. oracle设置自增字段,oracle序列
  10. (附源码)python 在线办公系统 毕业设计 071116
  11. samba服务testparm时提示rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)处理办法
  12. CMOS模拟集成电路笔记(第一部分)
  13. 怎么在qq空间引流?QQ空间生日栏怎么引流?
  14. Dubbo支持自适应等待无损下线
  15. eclipseWTP插件
  16. C. Qualification Rounds(状压思维)
  17. php 数独求解,php求解数独
  18. 上拉刷新下拉加载的实现
  19. python人工智能是什么意思_python人工智能是什么意思
  20. 二叉树系列(1)-实现排序二叉树

热门文章

  1. Phonegap在ios7上系统状态栏的问题解决
  2. 多个域名要选择合适的SSL证书
  3. namespace命名空间的使用
  4. 解决LSP问题导致无法上网
  5. java 遍历属性文件路径_Java项目中读取properties文件,以及六种获取路径的方法...
  6. 检测网络是否稳定的计算机命令,如何查看自己的网络是否稳定
  7. mysql查询自定义数据_实现自定义查询的数据库设计及实现(一)
  8. C++Primer学习之二#define,const,constexpr
  9. 数据库中的索引原理阅读
  10. 产品经理学SQL—前言