函数组件和类组件的本质区别
对于类组件来说, 底层只需要实例化一次, 实例中保存了组件的state等状态,每一次更新只需要调用render方法以及执行对应的生命周期函数。
对于函数组件来说,每一次更新都是一次新的函数执行, 一次函数执行, 里面的变量会重新声明, 为了能让函数组件保留一些状态,hooks出现了。
组件承担了渲染视图的UI和更新视图的useState, setState等方法。
函数组件
自React16.8, hooks出来的可以做类组件的事情, 替代函数组件, 函数组件不能prototype方法和属性,采用的是直接执行函数的方式, 不是new出来的。
类组件
类组件通过this.state定义状态, 通过this.setState更新状态。
生命周期方法:componentDidMount, componentDidUpdate, componentWillUnMount, shouldComponentUpdat
类组件的事件状态管理需要通过this来绑定上下文
类组件底层处理方法
funciton Component (props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue
}
Component.prototype.setState = function() {
}
Component.prototype.forceUpdate = function() {
}
问题: 如果在constructor中的super没传props, 接下来的constructor中执行上下文就获取不到props?
绑定props是在父类的Componen构造函数中, 执行super等同于执行Component函数, 如果super不传props, Component就接收不到这个参数, 就会为undefiend
如果有两个事件, class内部, 箭头函数直接绑定在实例上的, 实例上的方法 > 原型链上的方法
类组件生命周期函数
生命周期分成组件初始化, 组件更新, 组件卸载
组件初始化: constructor, static getDerviedStateFromProps, render, componentDidMount
组件更新: static getDerviedStateFromProps, shouldComponentUpdate, render, static getSnapshotBeforeUpdate, componentDidUpdate
组件卸载: componentWillUnMount
类组件生命周期: constructor, getDerviedStateFromProps, render, componentDidMount, shouldComponentUpdate, getSnapshotBeforeUpdate, componentDidUpdate, componetWillUnMount, getDerviedStateFromError, compontDidCatch
constructor(props)
- 作用:初始化组件的状态和绑定事件处理函数
- 调用时机:组件实例时调用
- 注意: 必须调用super(props), 要不然下面props为undefined, 不能在这里调用setState, 这里可以用this.state初始化数据
static getDerviedStateFromProps(props, state)
- 作用:在组件挂载或者更新时, 根据props更新state
- 时机:在render之前调用,无论是挂载还是更新阶段
- 返回值: 返回一个对象来更新state, 或者返回一个null不更新
render()
- 作用: 返回组件的jsx结构
- 掉用时机: 在挂载和更新阶段都会调用
- 注意: 必须是一个纯函数, 不能修改state或者与DOM交互, 如果返回null或者false, 不会更新组件
componentDidMount()
- 作用:组件挂载到DOM之后调用
- 调用时机: render之后掉用
- 用途: 网络请求,操作DOM
shouldComponentUpdate(nextProps, nextState)
- 作用: 决定组件是否重新渲染
- 掉用时机: render之前调用
- 返回值:true重新渲染, false不允许渲染
- 用途: 性能优化
getSnapshotBeforeUpdate(prevProps, prevState)
- 作用:在DOM更新之前获取快照,如滚动位置
- 调用时机:render之后, componentDidUpdate之前
- 返回值:返回一个快照值, 传给componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot)
- 作用:组件更新之后调用
- 调用时机: render之后调用
- 用途: 操作更新后的DOM, 根据props或者state发起网络请求
componetWillUnMount()
- 作用:组件卸载前调用
- 调用时机: 在组件从DOM移除之前
- 用途: 清除定时器,网络请求
static getDerviedStateFromError(error)
- 作用: 捕获子组件的错误并更新state
- 调用时机: 在子组件抛出错误前调用
- 返回值: 返回一个对象来更新state
compontDidCatch(error, errorInfo)
- 作用: 捕获子组件并且记录错误信息
- 调用时机:在子组件抛出错误后调用
函数组件hooks替代类组件生命周期函数方案
componentDidMount, componenntDidUpdate, componentWillUnMount
useEffect实现
useEffect(() => {
console.log('componentDidMount代替方案') // 只会第一次执行
}, [])
useEffect(() => {
console.log('componenntDidUpdate代替方案') // 根据state的更新执行
}, [state])
useEffect(() => {
retun function componentWillUnMount() {
console.log('清楚定时器')
}
}, [])