为什么我的组件会卸载?

时间:2017-11-28 14:14:32

标签: javascript reactjs

我在控制台中收到以下警告。

  

警告:只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState,replaceState或forceUpdate。这是一个无操作。

     

请检查ProgressBar组件的代码。

在我看来,这是因为componentWillUnmount发生在第一个componentDidMount之后(见底部的控制台输出)。 componentWillUnmount在数据从服务器到达之前发生。当数据最终到达时,setState正在尝试使用未安装的内容。

但为什么会有componentWillUnmount?我希望只有在调用setState(并且数据已从服务器到达)之后才会发生卸载。因此,该组件仍然可以与setState一起使用。

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

    loadProgressFromServer() {
        let url = '/progress/' + this.props.topic_name;
        console.log("LOADING progress FROM SERVER");
        $.ajax({
            url: url,
            datatype: 'json',
            cache: false,
            success: function(data) {
                console.log("finished loading from server");
                this.setState({ progress: data['progress'] });
            }.bind(this)           
        })
    }

    componentDidMount() {
        console.log("didmount");
        this.loadProgressFromServer();
    }

    componentWillUnmount() {
        console.log("willunmount");
    }

    render() {
        let progress = (this.state.progress * 100).toFixed(0);
        return (
            <div className="progress" ref="pb">
                <div className="progress-bar" role="progressbar" aria-valuenow={ progress } aria-valuemin="0" aria-valuemax="100" style={{ width: progress +"%" }}>
                    { progress + "%" }
                </div>
            </div>
        )
    }
}

控制台输出:

didmount
LOADING progress FROM SERVER
willunmount
didmount
LOADING progress FROM SERVER
finished loading from server
Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

Please check the code for the ProgressBar component.
finished loading from server

编辑: 没有更高阶的组件。

ReactDOM.render(
    <ProgressBar topic_name='name of topic' />,
    document.getElementById('progressbar')
);

1 个答案:

答案 0 :(得分:0)

看看是否有帮助(注意async: false) - async的默认值为true,它在呈现组件后从服务器返回数据 - 设置this.setState({ progress: data['progress'] });会导致出现警告消息获得

loadProgressFromServer() {
        let url = '/progress/' + this.props.topic_name;
        console.log("LOADING progress FROM SERVER");
        $.ajax({
            url: url,
            async: false
            datatype: 'json',
            cache: false,
            success: function(data) {
                console.log("finished loading from server");
                this.setState({ progress: data['progress'] });
            }.bind(this)           
        })
    }