4

react17的版本更新了,做了一些更新,最近学习了新版的生命周期,来使用对比16.8的版本

旧版本:
16.8生命周期

新版本:
image

可以看到新版的生命周期中 componentWillMount, componentWillReceiveProps, componentWillUpdate 三个生命周期被干掉了,其实还没被干掉,使用时会报警告:(componentWillReceiveProps也一样的警告)
image.png

为啥推荐加 UNSAFE_ 前缀,官方说明:新生命周期差异
目的是为了react18版本的 异步渲染更新,请移步官方去查看具体:异步渲染更新新特性探索

新生命周期里面,有两个函数 getDeriveStateFromPropsgetSnapshotBeforeUpdate

getDeriveStateFromProps

从props获取一个派生的状态,在调用 render 方法之前调用,函数必须返回一个状态对象或者 null,

// 使用方法,必须加 static !!!
static getDerivedStateFromProps(props, state)

如果在 getDerivedStateFromProps 中返回了一个状态对象(跟定义的state中一样),视图中的值会被函数返回值拦截并赋值为当前函数返回的状态对象中的值,并且对state内容操作,视图也不会更新(卸载组件还是没影响)。

使用很少

// state的值跟随props值变更而变更
// 例如判断props内值是奇数还是偶数,来确定用state还是用props
// 官方举例实现 <Transition> 组件很容易,跟随信息判断哪些组件做动画
static getDerivedStateFromProps(props, state) {
    props.xx === xx ? props : state;
}

getSnapshotBeforeUpdate

获取更新前的快照,从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()。应返回 snapshot 的值(或 null

什么是 snapshot ??

答案是什么都可以!!!灵活的js,哈哈哈

结合上述,我们的 componentDidUpdate() 方法中的参数就应该是 prevProps, prevState

来个例子,滚动位置定位

class NewsList extends React.Component{
    state = {newsArr:[]}
    componentDidMount(){
        setInterval(() => {
            //获取原状态
            const {newsArr} = this.state
            //模拟一条新闻
            const news = '新闻'+ (newsArr.length+1)
            //更新状态
            this.setState({newsArr:[news,...newsArr]})
        }, 1000);
    }
    getSnapshotBeforeUpdate(){
        // 返回每一条新闻的高度,就是我们说的,
        return this.refs.list.scrollHeight
    }
    componentDidUpdate(prevProps, prevState, height){
        // 计算滚动到当前想显示的条目位置并且保持不动
        // height就是我们说的 snapshot 的值!!!!
        this.refs.list.scrollTop += this.refs.list.scrollHeight - height
    }
    render(){
        return(
            <div className="list" ref="list">
                {
                    this.state.newsArr.map((n,index)=>{
                        return <div key={index} className="news">{n}</div>
                    })
                }
            </div>
        )
    }
}
ReactDOM.render(<NewsList/>,document.getElementById('test'))

万年打野易大师
1.5k 声望1.1k 粉丝