美文网首页
react--componentWillReceiveProps

react--componentWillReceiveProps

作者: Mr君 | 来源:发表于2019-08-03 21:05 被阅读0次

    一直不能理解在新版本中componentWillReceiveProps这个生命周期要被移除的原因,学艺不精啊,官方给出的componentWillReceiveProps被调用是在props发生改变的时候,感觉很合理啊,后来也是在官方早已经链接的相关博客里,找到了答案

    class Component extends React.Component {
      componentWillReceiveProps(nextProps) {
        console.log('componentWillReceiveProps', nextProps.data.bar);
      }
      render() {
        return <div>Bar {this.props.data.bar}!</div>;
      }
    }
    
    var container = document.getElementById('container');
    
    var mydata = {bar: 'drinks'};
    ReactDOM.render(<Component data={mydata} />, container);
    ReactDOM.render(<Component data={mydata} />, container);
    ReactDOM.render(<Component data={mydata} />, container);
    

    此时控制台会连续打印2次nextProps.data.bar,原因很简单,React并不知道数据没有改变,且组件需要知道新的props的值(即使它的值并没有改变),因此调用了生命周期componentWillReceiveProps
    原文也解释了为什么React没有进行深比较的原因,考虑如下三种情况

    1. 传入复杂类型,如Object,当遇到嵌套层级较深时,React对其进行深比较的时候,开销会很大。
    2. 传入的时一些实例的时候,React也是无法比较的。
    3. 当传入的值为引用闭包的时候,React无法检查到相关内容。

    当然上面给出的例子在我们日常开发中并不常见,我想到另外一个例子加以佐证:

    import React, { useState, useEffect } from "react";
    import ReactDOM from "react-dom";
    
    class Component extends React.PureComponent {
      componentWillReceiveProps(nextProps) {
        console.log("componentWillReceiveProps", nextProps.data.bar);
      }
      render() {
        return <div>Bar {this.props.data.bar}!</div>;
      }
    }
    
    function Example() {
      const [count, setCount] = useState(0);
      const data = { bar: "drinks" };
    
      setInterval(() => {
        setCount(count + 1);
      }, 100);
    
      return (
        <div>
          <Component data={data} />
        </div>
      );
    }
    
    ReactDOM.render(<Example />, document.getElementById("root"));
    

    或者

    function Example() {
      const [count, setCount] = useState(0);
      const [data, setData] = useState("drinks")
    
      const time = setTimeout(() => {
          clearTimeout(time)
        setCount(count + 1);
      }, 100);
      return (
        <div>
          <Component data={data} />
        </div>
      );
    }
    

    效果都是一样的,上面的例子中我们只是在更新state中count,导致父组件在rerender,子组件在不停的调用componentWillReceiveProps方法

    image.png
    因而componentWillReceiveProps这个声明周期其实并不是向我们最初理解的那样,它会带来一些副作用,因而现在官方给出了三种替代它的方式:
    1. 一些有副作用的操作,如:操作dom,network request等放在componentDidUpdate里来执行
    2. 当因为props改变而导致需要重新计算一些数据当时候,可以写在memoization中
    3. 当需要props改变时更新state的,可以放在完全受控组件中,或者通过key来控制。

    相关文章

      网友评论

          本文标题:react--componentWillReceiveProps

          本文链接:https://www.haomeiwen.com/subject/nvlsdctx.html