组件化的发展历程
面向对象:封装 集成 多态
模块化:13-16年 解决了全局变量和变量勿滥
组件化:使编程更轻量化
创建组件
组件的使用
- 无需注册
- 跟html标签书写一致
- 首字母大写
- 必须有根标签
- 一个组件一个模块
组件生命周期钩子函数
从出生到成长,最后到死亡,这个过程的时间可以理解为生命周期。React的生命周期同理也是这么一个过程。
React的生命周期分为三个阶段:挂载期(也叫实例化期)、更新期(也叫存在期)、卸载期(也叫销毁期)。在每个周期中React都提供了一些钩子函数。
生命周期的描述如下:
挂载期:一个组件实例初次被创建的过程。
更新期:组件在创建后再次渲染的过程。
卸载期:组件在使用完后被销毁的过程。那么钩子函数是什么呢?就是不同阶段要去做不同的事
初次挂载
constructor(构造函数,初始化状态值):组件第一次挂载被执行,只执行一次
componentWillMount(首次渲染前执行):react第一次挂载,在render之前,数据和模板进行拼接之前,render之前最后可以修改状态的机会,是数据最后可以修改的地方
render(渲染组件):数据和jsx拼接的地方,是纯函数,不做数据的存储与产生,制作数据的处理,每次props和state更新他都会重新渲染
componentDidMount(render渲染之后的操作):当组件真正的渲染到浏览器中去才执行且执行一次,放ajax请求。在终端运行 yarn add axios,插入import axios from 'axios',然后再componentDidMount里调用ajax请求
更新阶段
componentWillReceiveProps:父组件的数据传入子组件state的时候,父组件的改变会影响子组件的改变,该方法被调用
shuldComponentUpdate:当组件state或props的数据改变的时候,我们的组件要不要进行刷新,重新渲染,返回false会阻止render的调用
componentWillUpdate:更新阶段,数据和模板拼接之前,最后改变数据的一个地方
componentDidUpdate:更新阶段,最新的dom节点渲染到浏览器中
销毁之前
componentWillUnmount:解决一些事件的监听和释放dom操作,在删除组件之前进行清理操作,比如计时器和监听器。
老生命周期的问题
1.componentWillMount ,在ssr中 这个方法将会被多次调用, 所以会重复触发多遍,同时在这里如果绑定事件,将无法解绑,导致内存泄漏 , 变得不够安全高效逐步废弃。
2. componentWillReceiveProps 外部组件多次频繁更新传入多次不同的 props,会导致不必要的异步请求
3.componetWillupdate, 更新前记录 DOM 状态, 可能会做一些处理,与componentDidUpdate相隔时间如果过长,会导致状态不太好
新生命周期的代替
1.getDerivedStateFromProps 第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子) , 返回一个对象作为新的state,返回null则说明不需要在这里更新state
//老的生命周期的写法
componentDidMount() {
if(this.props.value!==undefined){
this.setState({
current:this.props.value
})
}
}
componentWillReceiveProps(nextProps){
if(nextProps.value !==undefined){
this.setState({
current:nextProps.value
})
}
}
//新的生命周期的写法
static getDerivedStateFromProps(nextProps) {
if(nextProps.value!==undefined){
return {
current:nextProps.value
}
}
return null
}
2.getSnapshotBeforeUpdate 取代了 componetWillUpdate ,触发时间为update发生的时候,在render之后 dom渲染之前返回一个值,作为componentDidUpdate的第三个参数。
//新的数据不断插入数据前面, 导致我正在看的数据向下走,如何保持可视区依旧是我之前看的数据呢?
getSnapshotBeforeUpdate(){
return this.refs.wrapper.scrollHeight
}
componentDidUpdate(prevProps, prevState,preHeight) {
//if(preHeight===200)return ;
this.refs.wrapper.scrollTop +=this.refs.wrapper.scrollHeight-preHeight
}
<div style={{height:"200px",overflow:"auto"}}} ref="wrapper">
<ul>
.........
</ul>
</div>
react中性能优化的方案
1.shouldComponentUpdate
控制组件自身或者子组件是否需要更新,尤其在子组件非常多的情况下, 需要进行优化。
2.PureComponent
PureComponent会帮你 比较新props 跟 旧的props, 新的state和老的state(值相等,或者 对象含有相同的属性、且属性值相等 ),决定shouldcomponentUpdate 返回true 或者 false, 从而决定要不要呼叫 render function。
注意: 如果你的 state 或 props 『永远都会变』,那 PureComponent 并不会比较快,因为 shallowEqual 也需要花时间。