React学习
- constructor组件创建的时候第一个执行的函数
Fragment占位符 不需要在外层在包裹一个额外的div标签
react原则上不允许在最外层出现多个同级的标签,而在外面在包裹一层会显得多余,Fragment可以解决
尽可能的往this.setState里传递一个函数而不是一个对象
this.setState是异步的,不要指望它会立即映射为新的值、
在事件处理函数是异步的,这样可以确保性能
往setState传递一个函数会保证里面的state为最新的
Jquery直接操作DOM叫命令式的代码
React叫做声明式的开发,面向数据开发,组件化的开发, 视图层的框架
- 函数式编程(一个个函数来组成的) -》 有利于自动化的测试,只要测试每一个函数的输入输出是否正确。
- 视图层的框架 -》 react在大型框架的时候只能搭建成视图,必须辅以redux,mobx等来管理状态数据
- 单向的数据流 -》 父组件向子组件的时候,不要在子组件里改变父组件的值,可以调用父组件的函数来修改父组件的值(TodoItem.js)
setState接受一个参数prevState,表示之前的状态
this.setState((prevState) => ({
// [...arr] 扩展运算符,生成新数组,加入后面的心智inputvalue
list: [...prevState.list, prevState.inputValue],
inputValue: '' //清空输入框里的值
}))使用 PropTypes 进行类型检查
当一个组件的state或者props发生改变的时候的,render函数就会被重新执行
虚拟DOM
- Reat渲染流程(没有虚拟DOM的时候)
- state数据
- JSX模板
- 数据 + 模板 结合,生成真实的DOM
- state 发生改变
- 数据 + 模板 结合,生成真实的DOM,替换原始的DOM
如果每次改变页面结构的时候都去改变DOM的时候,会非常消耗性能,
- 有了虚拟DOM的时候
- state数据
- JSX模板
- 数据 + 模板,生成虚拟DOM(虚拟DOM就是原生的JS对象,用来描述真实DOM)
- 用虚拟DOM的结构,生成真实的DOM
- state 发生变化
- 生成新的虚拟DOM(极大的提升了性能)
- 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别(diff算法)
- 操作DOM,改变数据
React.createElement(‘div’, {}, ‘item’)
JSX -> 虚拟DOM(JS 对象) -> 真实的DOM
优点:
- 性能提升了。
- 它使得跨端应用得以实现。 React Native
diff算法
原则是数据发生改变,虚拟DOM发生改变
会调用setState方法,这也就是为什么setState会是一个异步的方法。
如果有三次setState,就会把这三次改变合并起来,做一次改变。同级比较的(同层虚拟DOM比较)
只比较一次,如果在第一层比较出差异,接下来的层数就不需要比较了,直接进行替换。key值比对(虚拟DOM)
每个DOM节点都带有一个key,用对应的key进行相互的DON比较,也是diff算法的一部分
- Ajax请求和API接口
尽量都放在componentDidMount里使用
因为这个函数只会调用一次,且没有任何副作用,其实放在componentWillMount和construcrot里也是可以的,但并不会保证无副作用 - react-transition-group react开源动画库
更好的使用react动画效果生命周期函数
指某一个时刻组件会自动执行的函数老版本的生命周期函数
- initialization
在constructor里初始化的数据 - Mounting(componentWillMount -> render -> componentDidMount)
- componentWillMount 在组件挂载之前被执行
- render 渲染函数,挂载组件
- componentDidMount 在组件挂载之后被执行
注: 这两种都只是在组件第一次渲染的时候执行,数据的更新不会影响他们的变化
- Updation 数据更新
- 对于state数据的更新
- shouldComponentUpdate 组件更新之前发生,相当于询问你组件是否需要更新嘛?需要返回true or false
注:如果shouldComponentUpdate返回true,则执行componentWillUpdate 否则,接下来的生命周期都不会被执行 - componentWillUpdate 组件将要更新
- render 更新组件,渲染
- componentDidUpdate 组件更新完成
- shouldComponentUpdate 组件更新之前发生,相当于询问你组件是否需要更新嘛?需要返回true or false
- 对于props的更新(多了第一步的componentWillReceiveProps的生命周期, 相当于询问子组件是否接受了参数,这个生命周期函数只对于子组件有效,放在顶层组件没有效果)
- componentWillReceiveProps 相当于询问子组件是否接受了参数
产生条件:
一个组件要从父组件接受参数
只要父组件的render函数被重新执行,子组件的这个生命周期函数函数就会被执行
接下来的步骤同于state数据的更新
- componentWillReceiveProps 相当于询问子组件是否接受了参数
- 对于state数据的更新
- Unmounting
- componentWillUnMount 在组件卸载及销毁之前直接调用
新版本的生命周期函数
- componentWillMount 和 componentWillReceiveProps将会被替换成
getDerivedStateFromProps函数
会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
性能优化
- react中绑定this指向时放在constructor里,保证绑定只会执行一次,不会做不必要的性能浪费
- setState函数有多个时,会被react进行异步的操作,放在一起进行操作,不会浪费性能。
- 虚拟DOM的优化
- shouldComponentUpdate生命周期函数的使用,可以避免多余的render的浪费