收到名为 Can't call setState on a component that is not mounted 的警告

Getting a warning called Can't call setState on a component that is not yet mounted

这是我的代码

import React, { Component } from 'react';

class Rando extends Component {
    constructor(props) {
        super(props); // want to use props insode brackets if we want to use props inside the constructor
        this.state = { num: 0, color: 'purple' };
        this.makeTimer();
    }

    makeTimer() {
        setInterval(() => {
            let rand = Math.floor(Math.random() * this.props.maxNum);

            this.setState({ num: rand });
        }, 10);
    }
    render() {
        console.log('changing');
        return (
            <div className=''>
                <h1>{this.state.num}</h1>
            </div>
        );
    }
}

export default Rando;

我收到如下所示的警告

index.js:1 警告:无法在尚未安装的组件上调用 setState。这是一个空操作,但它可能表示您的应用程序中存在错误。相反,直接分配给 this.state 或在 Rando 组件中定义具有所需状态的 state = {}; class 属性。

我是初学者,我不知道是什么原因造成的。请帮我。提前致谢

您应该在 componentDidMount() 上调用 this.makeTimer(); 而不是 constructor

componentDidMount(){
  this.makeTimer();
}

试试这个代码

import React, { Component } from 'react';

class Rando extends Component {
    constructor(props) {
        super(props); // want to use props insode brackets if we want to use props inside the constructor
        this.state = { num: 0, color: 'purple' };
        this.makeTimer((data) => {
          this.setState(data);
        });
    }

    makeTimer(cb) {
        setInterval(() => {
            let rand = Math.floor(Math.random() * this.props.maxNum);

            
            cb({ num: rand })
        }, 10);
    }
    render() {
        console.log('changing');
        return (
            <div className=''>
                <h1>{this.state.num}</h1>
            </div>
        );
    }
}

export default Rando;

试试这个:

import React, { Component } from 'react';

class Rando extends Component {
    constructor(props) {
        super(props); // want to use props insode brackets if we want to use props inside the constructor
        this.state = { num: 0, color: 'purple' };
    }

    makeTimer() {
        setInterval(() => {
            let rand = Math.floor(Math.random() * this.props.maxNum);

            this.setState({ num: rand });
        }, 10);
    }

    componentDidMount(){
    this.makeTimer();
    }

    render() {
        console.log('changing');
        return (
            <div className=''>
                <h1>{this.state.num}</h1>
            </div>
        );
    }
}

export default Rando;

您的计时器功能甚至在组件安装之前就已执行。尝试将代码放入 componentDidMount 钩子中。也不要忘记清除 componentWillUnmount.

中的间隔 id

沙盒link供您参考:https://codesandbox.io/s/react-basic-class-component-forked-sybv0?file=/src/index.js

修改后的代码段

import React, { Component } from 'react';

class Rando extends Component {
    constructor(props) {
        super(props); 
        this.state = { num: 0, color: 'purple' };
        this.timer = null;
    }

     componentDidMount() {
        this.makeTimer();
     }
   
     componentWillUnmount() {
        clearInterval(this.timer);
     }

    makeTimer = () => {
        this.timer = setInterval(() => {
            let rand = Math.floor(Math.random() * this.props.maxNum);
            this.setState({ num: rand });
        }, 10);
    }

    render() {
        return (
            <div>
                <h1>{this.state.num}</h1>
            </div>
        );
    }
}

export default Rando;