新生命周期新增的两个钩子:
1. getDerivedStateFromProps :罕见的使用场景,如果state 的值在任何时候都取决于 props ,可以使用这个函数。但是代码会冗余,并且组件不好维护,不常使用。
2. getSnapshotBeforeUpdate :组件在更新之前来个快照。使用概率很低。
使用场景示例: 一个新闻列表固定高度,里面的内容是动态增加的,当拖动滚动条只想停留在当前新闻时,可以用到这个钩子。
代码如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>4. getSnapshotBeforeUpdate的使用场景</title> </head> <style> .list { width: 200px; height: 150px; overflow: auto; background-color: skyblue; } .news { height: 30px; } </style> <body> <div id="list"></div> <!-- 引入react核心库 --> <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <!-- 引入react-dom,用于支持react操作DOM --> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <!-- 引入babel,用于将jsx转为js --> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> <script type='text/babel'> class NewsList extends React.Component { state = { newsArr: [] } componentDidMount() { setInterval(() => { const { newsArr } = this.state const news = '新闻' + (newsArr.length + 1) this.setState({ newsArr: [news, ...newsArr] }) }, 1000) } render() { return ( <div className="list" ref="list"> { this.state.newsArr.map((n, index) => { return <div className="news" key={index}>{n}</div> }) } </div> ) } getSnapshotBeforeUpdate() { return this.refs.list.scrollHeight } componentDidUpdate(preProps, preState, height) { this.refs.list.scrollTop += this.refs.list.scrollHeight - height } } ReactDOM.render(<NewsList/>, document.getElementById('list')) </script> </body> </html>
效果如下图: 滚动条一直在缩短,内容在变长,但是列表是固定的,没有随着滚动条滚动
总结: 1. 初始化阶段: 由 ReactDOM.render() 触发 —— 初次渲染 1. constructor() 2. getDerivedStateFromProps 3. render() 4. componentDidMount() ===> 常用 一般在这个钩子中做一些初始化的事情。例如:开启定时器、发送ajax请求、订阅消息 2. 更新阶段: 由组件内部 this.setState() 或父组件重新 render 触发 1. getDerivedStateFromProps 2. shouldComponentUpdate() 3. render() ===> 常用 初始化渲染或更新渲染调用 4. getSnapshotBeforeUpdate() 5. componentDidUpdate() 3. 卸载组件: 由 ReactDOM.unmountComponentAtNode() 触发 1. componentWillUnmount() ====> 常用 一般在这个钩子中做一些收尾的事。例如:关闭定时器、取消订阅消息 即将废弃的钩子: 1. componentWillMount 2. componentWillReceiveProps 3. componentWillUpdate 现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。