2017-11-28 16 views
0

以下の警告がコンソールに表示されます。コンポーネントがアンマウントするのはなぜですか?

警告:マウントされているコンポーネントまたはマウントされているコンポーネントのみを更新できます。これは通常、マウントされていないコンポーネントに対してsetState、replaceState、またはforceUpdateを呼び出したことを意味します。これはノーオペレーションです。

ProgressBarコンポーネントのコードを確認してください。

理由最初componentDidMount後に起こるcomponentWillUnmount(下部のコンソール出力を参照)であるように思えます。 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 

EDIT: 何より高次のコンポーネントはありません。

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

_ "しかし、そこには" willunmount "があるのですか?" _あなたはそこに置いていませんでしたか? – Andy

+0

私の質問は、それが引き起こされる理由です。 AJAX要求が完了する前にコンポーネントがアンマウントされているのはなぜですか? – Andras

+0

上位コンポーネントは何をしていますか?私にとってはProgressBarとは異なるプロセスがProgressBarコンポーネントをアンマウントするようです。たぶんコンテナにajax呼び出しを処理させ、progressbarが実際に何が起きているのかを知ることなくProgressBarを更新する方が良いかもしれません – Schuere

答えて

0

それは場合に役立ちます(async: falseに注意してください)を参照してください - 非同期のデフォルト値が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)   
     }) 
    } 
+0

これは問題を解決します。警告は消え、アンマウントは "サーバーからのロード完了"の後にのみ発生します。それは減価償却されていますが、何が起こっているのか理解するためにはまだ多くの助けをしています。データが到着する前に 'setState'がどのようにトリガされたかは直感的ではありません。なぜなら、' success'はデータが到着した後にのみトリガされるからです。 – Andras

+0

メインスレッドの同期XHRは非常に長い間使用されなくなりました。 https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests – Adam

関連する問題