React入门级小白指北及常见问题解答

1.前言

最近学习使用 React 开发课程项目,作为刚接触React的新人,其中遇到一些解决方式很简答,但却也需要花时间去寻找答案的问题。本着为新人节约时间的目的,才有了这篇文章。注释,此样式文字说明其内容引用自官方文档内容。

2.合理定义组件 state

古语云,知其然知其所以然。在正式使用 React 前,理解其设计理念对于开发应用是十分有必要的,先来看看 React 的一些理念。

React 的众多优点之一是它让你在编写代码的时候同时也在思考你的应用。 React 官方文档的这句话,在应用拆分为组件,以及设计组件state的这个过程中体现的淋漓尽致。使用 React 开发应用的过程,也是不断在思考如何搭建应用的过程。

为了正确构建你的应用,首先你需要考虑你的应用所需要的最小可变状态集。 对于这句话的,我的理解是:组件中的 state 数据是用于记录组件当前交互的结果,而且 state 所记录的数据,应当做到既满足需求又不多余。那么如何去做到这些?官方文档中也给出了标准,即三个问题: 1、它是通过 props 从父级传来的吗?如果是,它可能不是 state。 2、它随着时间推移不变吗?如果是,它可能不是 state。 3、你能够根据组件中任何其他的 state 或 props 把它计算出来吗?如果是,它不是 state。

问题一很好理解,数据如果可以从父级组件那里拿到,那么就可以在 render 中现拿现用,没必要再设置一个多余的 state。

问题二也很简单,但是我认为会是新人最容易犯错误的一点,包括我自己。如果组件里有一个定值,那么完全可以通过正常的定义变量去记录,而不是把 state 当作变量去使用。

问题三与问题一类似,如果某个数据能从其它组件那里传递过来的数据计算得来,那么也没必要设置成 state。简单来说,知道了矩形的长与宽,那么面积自然就可以求出来,没必要再用一个 state 去记录矩形面积。 除了官方给出的三点之外,我认为还有标签的某些交互属性也不应设置为 state。比如结合 CSS 的属性选择器来控制标签的隐藏与显示,标签不会自发的去隐藏或显示,它肯定是交互的结果,那么依然可以从别的组件那里拿到数据来控制样式。

3.setState

setState方法设置数据是异步的! setState方法设置数据是异步的!! setState方法设置数据是异步的!!!

最初使用React的时候并不知道这个点,导致代码逻辑没有错误,但拿到的数据始终是unfinded。后来找了文档才知道原因是setState异步设置数据,那么自然下一条语句读取数据时是unfinded。 因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。

异步数据何时能正确设置是不确定的,那么自然根据它来计算下一个值也是不确定的,所以在代码里使用 state 数据时,做数据检验是十分必要的。不过好在 setState 方法可以拥有一个回调函数,当数据设置完毕后,就调用这个函数,写法如下:

第一个参数是 state 对象属性的设置,第二个参数是回调函数,使用了 ES6 箭头函数的语法。

4.状态提升与单向数据流

使用 react 经常会遇到几个组件需要共用状态数据的情况。这种情况下,我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理。

根据上文设计 state 数据的原则,state 数据应当做到最小可变状态集,那么如果某个状态数据是几个组件都需要且相同的,那么分别设置在组件中显然不合适,显得冗余。这时候最佳的方式就是将这些共用的state数据提升至离需要这些数据的组件最近的父组件来完成,这就是所谓的状态提升。

既然共享的状态数据都会提升至它们最近的父组件当中,那么当其子组件需要数据时,都会从它们的父组件里去拿。这样数据就是从一个父组件流向多个子组件,也就是单向数据流。

在React应用中,对应任何可变数据理应只有一个单一“数据源”。……你应该在应用中保持自上而下的数据流,而不是尝试在不同组件中同步状态。这样的数据流像瀑布一样,最高层有一个唯一的源头,从上至下传输数据到每个组件。而这样做的好处则是你也可以更快地寻找和定位bug的工作。因为哪个组件保存有状态数据,也只有它自己能够操作这些数据,发生bug的范围就被大大地减小了。

至此,React三个重要的理念就介绍完了,再回到开始的那句话它让你在编写代码的时候同时也在思考你的应用。不管是在应用开发前的分析数据流,拆分模块,还是开发过程中不断凝练、简化state,组件更细致化,React都要求你要去不断思考自己的应用,如何让应用的思路更清晰,更具模块性。

5.React中常见功能的实现

5.1本地图片的引用

要使用本地图片,首先得安装两个npm包: url-loader(https://www.npmjs.com/package/url-loader) file-loader(https://www.npmjs.com/package/file-loader)

理论上来说url-loader封装了file-loader,只需要安装url-loader即可。但在实际使用中 Chrome 调试里还是看到了关于file-loader的错误,于是我两者都安装了,使用方法如下。

webpack.config.js文件配置,如图:‍

组件中引用方式,如图:

5.2滚动事件的绑定 只需在内容超出的标签上使用 overflow: scroll 样式即可出现滚动条,但滚动事件的绑定,让我费了一些时间。在网上找到一种使用 window.addEventListener 监听滚动事件的办法,可我没有试成功,望知道的朋友告知下。于是我使用另一种方法,组件代码如下:

这里要说明的是 ref 属性的用法,可以在函数里使用 console.log(this) 将组件对象输出到控制台,展开返回的对象属性就能看到添加了 ref 属性的标签全都在 refs 属性里。根据属性路径读取它,就能返回这个标签实例。我自己的理解是,它就像 DOM 里的document.getElementById(id)方法一样,只是把标签的 id 属性换成了 ref 属性。 5.3map遍历对象数组错误 在使用map函数(array.map(function(currentValue, index, arr), thisValue))遍历对象数组生成 li 列表时,有时会出现如下错误:

原因是这时 currentValue 传递的是一个对象(Object),而不是一个数值(String, Nubmer等等),因此才会提示在这个对象中还找到了相关的键值。

所以,如果遍历的数组是[1, 2, 3, 4……]这样的结构的,currentValue传递的是数值,会正常渲染。而遍历的数组是[{name: a}, {name: b}, {name: c}……]这样的对象集合,则会有错误提示发现还有name这个键值。不过可以通过 currentValue.name 这样写来获得数值,也是可以通过的。

有一点例外就是 currentValue 作为 props 传递给 React 自定义组件的话,即使是对象(Object)也是可以的。

原文作者:IMWeb 魔

原文链接:http://imweb.io/topic/5aa54d6c16bc830d673d42ee

原文发布于微信公众号 - 腾讯NEXT学位(NextDegree)

原文发表时间:2018-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

10个短小却超实用的JavaScript代码段

JavaScript正变得越来越流行,它已经成为前端开发的第一选择,并且利用基于JavaScript语言的NodeJS,我们也可以开发出高性能的后端服务,甚至我...

21380
来自专栏nice_每一天

一天带你入门到放弃vue.js(三)

自己新建的标签赋予特殊功能的是组件,而指定是在标签上使用类似于属性,以v-name开头,v-on,v-if...是系统指令! v-是表示这是vue的指令if,f...

15610
来自专栏Python绿色通道

Python爬虫:现学现用xpath爬取豆瓣音乐

爬虫的抓取方式有好几种,正则表达式,Lxml(xpath)与BeautifulSoup,我在网上查了一下资料,了解到三者之间的使用难度与性能

23030
来自专栏IMWeb前端团队

React + Redux 组件化方案

React + Redux 组件化方案 在介绍组件化方案之前,先对 react 和 redux 做一个简单介绍。 Why React 理想中的组件化,第一步应该...

23280
来自专栏腾讯移动品质中心TMQ的专栏

Web 自动化:一种基于 Page Object 的实现及常见异常处理

Page Object 设计模式是 Selenium 官网推荐的一种自动化构建模式。PageObject 设计模式对网页进行一个简单抽象,将每个页面设计成一个类...

23400
来自专栏hrscy

Unity 基础 - Input 类

任何一款游戏都必须和用户进行交互才行,最常用的就是通过键盘和鼠标进行交互,在 Unity 中想要获取用户的键盘或鼠标的事件的话,就必须使用 Input 类来获取...

16430
来自专栏程序员的知识天地

web前端开发规范总结

Web前端作为开发团队中不可或缺的一部分,需要按照相关规定进行合理编写(一部分不良习惯可能给自己和他人造成不必要的麻烦)。不同公司不同团队具有不同的规范和文档。...

46520
来自专栏数值分析与有限元编程

打造高颜值的Python IDLE

与其他IDE相比,Python自带的IDLE给人的感觉就是一个字--土,就像一个不会打扮的女人。其实我们可以让他高大上一些,这样敲出的代码就赏心悦目,比如像下面...

50950
来自专栏我和我大前端的故事

Vue 父子组件数据传递( inheritAttrs + $attrs + $listeners)

当我们在书写 vue 组件的时候,也许可能会用到数据传递;将父组件的数据传递给子组件,有时候也需要通过子组件去事件去触发父组件的事件;

27430
来自专栏快乐八哥

CSS3制作心形头像

1.功能需求: 最近有一个基于微信开发的Mobile Web项目,是一个活动页面。功能需求:用户使用微信扫描二维码,然后授权使用微信登录,然后读取用户的昵称和头...

302100

扫码关注云+社区

领取腾讯云代金券