react、redux个人学习笔记

时间:2022-12-28 11:07:51

react、redux个人学习笔记


本文记录了个人在学习过程中爬过的坑,仅供参考,大牛绕道,若有说的不对的地方欢迎批评指正,希望能帮到一些和我一样刚刚开始学习React的新手。


State、 Actions与Reducer

使用react与redux相结合的框架构造项目的时候,其核心无非就是store, actions与reducer三者相结合。核心思想非常好理解,store中的state用于存储数据以控制组件的状态,而组件所涉及的各种行为称为actions,但actions只是一个含有type属性和相应数据的json对象,并不处理数据,只是起到一个命令的作用。当某个action被dispatch调用后会根据action中的type属性值在reduder里寻找对应项,真正对数据进行操作的是reducer,然后reducer将action中携带的数据进行一定处理后更新到store的state中,而当state一旦发生改变,React中的diff算法会根据state的改变部分对相应组件进行最小程度的重新渲染。


React组件生命周期

这张图片很好的显示了React组件的生命周期,了解并牢记各个生命周期的执行顺序和触发条件的重要性我就不强调了。
react、redux个人学习笔记

值得一提的是componentWillReceiveProps这个环节,在该组件第一次被渲染的时候,该方法并不会被调用,而在第一次渲染之后props发生改变之后才会触发该函数。另外,当调用该组件的父组件的state发生改变的时候,父组件中所有的子组件都会触发一次componentWillReceiveProps方法,即使其发生改变的state与某个子组件没有任何关系。因此,当你想在父组件中state添加某个值的时候,一定要三思而后行,可能会导致子组件意外的触发componentWillReceiveProps方法。


React组件内的state

除了store中的state外,各个组件也有自己的state,用于控制组件自身的状态,切勿将两个state弄混淆。需要注意的是,组件内调用this.setState(newState)之后,newState会被加入到一个队列中(如下图所示),不会立即执行更新,而是会触发一个判断条件来判断是否需要马上更新。所以当你调用this.setState(newState)之后,马上从state中拿值很可能是拿不到newState的。而且在对state中同一个值进行连续赋值的时候,state并不会重复更新,而是只会直接将相应的值更新为最后一次赋值结果。
react、redux个人学习笔记


数据传递

关于数据传递,必须要提的是我在初学React时遇到的一个坑,就是当父组件通过props向子组件传递数据(Array数组)的时候,在子组件的constructor,componentWillMount等方法中拿不到this.props.data的值,而其它的如Boolean、String、Number类型数据能够正常获取。

constructor(props) {
super(props);
console.log(this);
console.log(this.props.contentData);
}

如上方代码,在Table组件中constructor方法里用控制台分别打印 this 和 this.props.data:

react、redux个人学习笔记

我们发现this.props.data是个空数组,然后再查看Table中的props:

react、redux个人学习笔记

我们发现Table里的props中的contentData却是拿到了的。为什么会出现这种前后不一致的情况呢。这个奇怪的现象其实是由两个原因导致的,第一个原因是因为chrome浏览器控制台在记录某个具有多层次的数据结构时,其实记录下来的只是该数据结构的一个快照(snapshot),意思是指控制台在执行记录时,其实只记录了这个数据结构的最表面一层,而当你之后再去查看内层数据的时候,内层数据的值才会被获取,也就是说你现在看到的内层数据的值都不是执行console.log代码的那一瞬间的值,而是你在控制台查看内层数据的这一时刻的值。而控制台仅仅只在执行代码的瞬间记录下一个快照的目的是为了让控制台最小程度的影响程序代码的执行,而一次性记录下整个复杂的数据结构则会损失一部分效率。

react、redux个人学习笔记

回到Table组件中的constructor方法中来,现在我们知道了其实在constructor方法中我们确实是没有拿到数据,console.log(this)中所看到的数据其实是个假象,那为什么只有这个数组数据拿不到,其它的props却能够正常获取呢?原来第二个原因是由于为了保持子组件的通用性,相关数据往往不是由子组件去获取,而是由父组件在componentWillMount方法中将相关数据存入到store中,然后通过mapStateToProps方法从store中的state里拿到然后数据再传到对应子组件中的,然而mapStateToProps执行顺序在componentWillMount之前,整个过程执行顺序是:mapStateToProps,componentWillMount,render,componentWillReceiveProps,render。所以第一次渲染时传到子组件里的数据是store里的初始state,也就是上方控制台显示的空数组,然而子组件的constructor只有在组件初始化时才会调用,所以自然就出现拿不到数据的尴尬情况。这也是有时候组件第一次渲染的时候连续渲染两次的原因(因为第一次渲染的时候数据是空的,真正的数据传过来的时候马上进行第二次渲染)。
为了避免这种情况的解决办法是在父组件渲染时对相应数据进行判断,只有当确认数据已经拿到了才渲染对应子组件,也就不会出现上述中的奇怪现象了。

To be continued…