如果任何基于父类的组件收到新的道具但未设置状态...是否将调用componentDidMount

问题描述

我正在学习最近3个月的反应,没有清楚地得到1件事。.我想知道,如果我的顶级应用程序组件获得了新的道具,但没有调用任何设置的状态...会调用吗组件“未安装”?或将不会调用任何组件“已安装”。

解决方法

如果已安装组件,它将不会再次调用componentDidMount,否。但它会(暂时)调用旧的componentWillReceiveProps/UNSAFE_componentWillReceiveProps,并将调用rendercomponentDidUpdate

尝试这些方法很容易。例如:

class Parent extends React.Component {
    constructor(props) {
        super(props);
        console.log("Parent - constructor");
    }

    componentDidMount() {
        console.log("Parent - componentDidMount");
    }

    UNSAFE_componentDidReceiveProps() {
        console.log("Parent - UNSAFE_componentDidReceiveProps");
    }

    componentDidUpdate() {
        console.log("Parent - componentDidUpdate");
    }

    render() {
        console.log("Parent - render");
        const { value } = this.props;
        return <Child value={value} />;
    }
}

class Child extends React.Component {
    constructor(props) {
        super(props);
        console.log("Child - constructor");
    }

    componentDidMount() {
        console.log("Child - componentDidMount");
    }

    UNSAFE_componentDidReceiveProps() {
        console.log("Child - UNSAFE_componentDidReceiveProps");
    }

    componentDidUpdate() {
        console.log("Child - componentDidUpdate");
    }

    render() {
        console.log("Child - render");
        const { value } = this.props;
        return <div>value = {value}</div>;
    }
}

class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            counter: 0
        };
    }

    componentDidMount() {
        setTimeout(() => {
            this.timer = setInterval(() => {
                this.setState(({counter}) => {
                    ++counter;
                    if (counter === 2) {
                        clearInterval(this.timer);
                    }
                    return {counter};
                });
            },500);
        },1000);
    }

    render() {
        const { counter } = this.state;
        return <Parent value={counter} />;
    }
}

ReactDOM.render(<Example />,document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>