1.生命周期钩子函数(旧)

image.png

1.1 组件挂载

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(props) {
  4. super(props)
  5. console.log('constructor')
  6. }
  7. //初始化状态
  8. state = {
  9. count: 0,
  10. }
  11. add = () => {
  12. let { count } = this.state
  13. this.setState({
  14. count: ++count,
  15. })
  16. }
  17. // 組件挂在之前執行
  18. componentWillMount(){
  19. console.log('componentWillMount')
  20. }
  21. // 组件挂载之后执行
  22. componentDidMount(){
  23. console.log('componentDidMount');
  24. }
  25. render() {
  26. console.log('render');
  27. return (
  28. <div>
  29. <h2>count当前的值:{this.state.count}</h2>
  30. <button onClick={this.add}>+</button>
  31. </div>
  32. )
  33. }
  34. }
  35. export default App

:::success 页面初始化阶段: 由ReactDOM.render()触发 ——初次渲染

  • constructor
  • componentWillMount
  • render
  • componentDidMount :::

    1.2组件更新

    ```javascript import React from ‘react’ class App extends React.Component { constructor(props) { super(props) console.log(‘constructor’) } //初始化状态 state = { count: 0, } add = () => { let { count } = this.state this.setState({
    1. count: ++count,
    }) } // 卸载组件的方法 death = () => { // React.unmountComponentAtNode(document.getElementById(‘app’)); } // 組件挂在之前執行 componentWillMount(){ console.log(‘componentWillMount’) } // 组件挂载之后执行 componentDidMount(){ console.log(‘componentDidMount’); } // 组件卸载之后 componentWillUnmount(){ console.log(‘componentWillUnmount’) } // 组件是否需要更新 shouldComponentUpdate(){ console.log(‘shouldComponentUpdate’); return true } // 组件将要更新 componentWillUpdate(){ console.log(‘componentWillUpdate’); } // 组件更新之后 componentDidUpdate(){ console.log(‘componentDidUpdate’) } render() { console.log(‘render’); return (
    1. <div id='app'>
    2. <h2>count当前的值:{this.state.count}</h2>
    3. <button onClick={this.add}>+</button>
    4. <button onClick={this.death}>卸载组件</button>
    5. </div>
    ) } } export default App
  1. :::success
  2. **页面更新阶段:**由组件内部this.setSate()或父组件重新render触发,且shouldComponentUpdate返回true, 则执行顺序为:
  3. - **shouldComponentUpdate(nextProps, nextState)**
  4. - **componentWillUpdate**
  5. - **render**
  6. - **componentDidUpdate**
  7. :::
  8. **注意:**
  9. - 如果shouldComponentUpdate返回false,则不执行下面的钩子函数;
  10. - 如果组件中不屑shouldComponentUpdate,那么组件会默认的加这个钩子, 且返回值是true;
  11. <a name="tXD17"></a>
  12. ## 1.3强制更新组件
  13. ```javascript
  14. import React from 'react'
  15. class App extends React.Component {
  16. constructor(props) {
  17. super(props)
  18. console.log('constructor')
  19. }
  20. //初始化状态
  21. state = {
  22. count: 0,
  23. }
  24. add = () => {
  25. let { count } = this.state
  26. this.setState({
  27. count: ++count,
  28. })
  29. }
  30. // 卸载组件的方法
  31. death = () => {
  32. // React.unmountComponentAtNode(document.getElementById('app'));
  33. }
  34. //强制更新组件
  35. force = () => {
  36. console.log('强制更新');
  37. this.forceUpdate()
  38. }
  39. // 組件挂在之前執行
  40. componentWillMount(){
  41. console.log('componentWillMount')
  42. }
  43. // 组件挂载之后执行
  44. componentDidMount(){
  45. console.log('componentDidMount');
  46. }
  47. // 组件卸载之后
  48. componentWillUnmount(){
  49. console.log('componentWillUnmount')
  50. }
  51. // 组件是否需要更新
  52. shouldComponentUpdate(){
  53. console.log('shouldComponentUpdate');
  54. return true
  55. }
  56. // 组件将要更新
  57. componentWillUpdate(){
  58. console.log('componentWillUpdate');
  59. }
  60. // 组件更新之后
  61. componentDidUpdate(){
  62. console.log('componentDidUpdate')
  63. }
  64. render() {
  65. console.log('render');
  66. return (
  67. <div id='app'>
  68. <h2>count当前的值:{this.state.count}</h2>
  69. <button onClick={this.add}>+</button>
  70. <button onClick={this.death}>卸载组件</button>
  71. <button onClick={this.force}>强制刷新页面</button>
  72. </div>
  73. )
  74. }
  75. }
  76. export default App

:::success 强制更新:forceUpdate()

  • componentWillUpdate
  • render
  • componentDidUpdate :::

    1.4 componentWillReceiveProps:

    componentWillReceiveProps在初始的时候不会被调用, 它在组件接收到新的props时调用。 一般用于父组件更新状态时子组件重新渲染。
    在React6.3之前,componentWillReceiveProps是在不进行额外render的前提下,相应props中改变并更新state的唯一方式。

    1. componentWillReceiveProps(nextProps){
    2. //通过this.props来获取旧的外部状态, 初始props不会被调用
    3. //通过对比新旧状态, 来判断是否执行其他方法
    4. }

    2. 生命周期钩子函数(新)

    2.1 新版本中废弃掉3个旧版本的钩子函数:

  • componentWillMount

  • componentWillUpdate
  • componentWillReceiveProps

注意:现在使用会出现警告, 下一个版本需要加上UNSAFE_前缀才能使用, 以后会彻底废弃, 不建议使用。
react生命周期(新).png

2.2 getDerivedStateFromProps:

getDerivedStateFromProps(props, state): 会在调用render方法之前调用, 并且在初始挂载及后续更新时都会被调用, 它应该返回一个对象来更新state, 如果返回null则不更新任何内容。
此方法使用场景:state的值在任何时候都取决于props.

  1. static getDerivedStateFromProps(props, state){
  2. }

2.3 getSnapShotBeforeUpdate():

getSnapShotBeforeUpdate(prevProps, prevState): 在最近一次渲染输出(提交到DOM节点)之前调用。 它使得组件在发生改变之前从DOM中捕获一些信息(例如: 滚动位置)。此生命周期方法的任何返回值将作为参数传递给componentDidUpdate

  1. import React from 'react';
  2. import './index.css'
  3. class Home extends React.Component {
  4. constructor(props){
  5. super(props)
  6. console.log('count:constructor ');
  7. }
  8. state = {
  9. newsArr:[]
  10. }
  11. componentDidMount(){
  12. setInterval(() => {
  13. const { newsArr } = this.state;
  14. //模拟一条新闻
  15. const news = '新闻'+(newsArr.length + 1)
  16. //更新状态
  17. this.setState({
  18. newsArr:[news, ...newsArr]
  19. })
  20. },1000)
  21. }
  22. //组件更新前
  23. getSnapshotBeforeUpdate(){
  24. return this.list.scrollHeight
  25. }
  26. //组件已经更新
  27. componentDidUpdate(prevProps, prevState,height){
  28. console.log('count:componentDidUpdate', height);
  29. this.list.scrollTop += this.list.scrollHeight - height
  30. }
  31. render() {
  32. const { newsArr } = this.state;
  33. console.log('count:render' )
  34. return (
  35. <ul className='list' ref={ c => this.list = c}>
  36. {
  37. newsArr?.map( (item ,index) => {
  38. return <li key={index} className='listItem'>{item}</li>
  39. })
  40. }
  41. </ul>
  42. );
  43. }
  44. }
  45. export default Home;

2.4 新版生命周期钩子函数的三个阶段:

1. 初始化阶段: 由ReactDOM.render()触发——初次渲染 :::success

  • constructor()
  • getDerivedStateFromProps
  • render()
  • componentDidMount() ::: 2. 更新阶段: 由组件内部的this.setState()或父组件重新render触发 :::success

  • getDerivedStateFromProps

  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate ::: 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发 :::success componentWillUnmonunt() :::

    3. 总结

    总结:有三个重要的钩子:
    1. render: 初始化渲染或者组件更新调用
    2. componentDIdMount: 开始监听, 发送Ajax请求
    3. componentWillUnmount: 做一些收尾工作: 比如清理定时器;