美文网首页
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