jaychen

8 天前

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

本文作者:IMWeb jaychen 原文出处:IMWeb社区 未经同意,禁止转载

原文作者:IMWeb 魔 原文链接:React入门级小白指北及常见问题解答 - 腾讯Web前端 IMWeb 团队社区

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 箭头函数的语法,关于 state 更多知识的 官方文档点这里

推荐另一篇深入介绍 state 的文章,点击传送

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

使用 react 经常会遇到几个组件需要共用状态数据的情况。这种情况下,我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理。根据上文设计 state 数据的原则,state 数据应当做到最小可变状态集,那么如果某个状态数据是几个组件都需要且相同的,那么分别设置在组件中显然不合适,显得冗余。这时候最佳的方式就是将这些共用的state数据提升至离需要这些数据的组件最近的父组件来完成,这就是所谓的状态提升。

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

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

5.React中常见功能的实现

5.1 本地图片的引用

要使用本地图片,首先得安装两个npm包: url-loader,详情点击 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.3 map遍历对象数组错误

在使用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)也是可以的。


前端NEXT学位课程第六期正在招生中!感兴趣的小伙伴快点击这里,了解课程详情吧!

更多干货与福利请关注公众号【腾讯NEXT学位】!

0条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。