2017-10-07 2 views
0

私は小さな問題がありますが、それは私を混乱させます。 Reactコンポーネントのレンダリング機能で、ブートストラップスピナーを表示しています。 isSavingがTRUEであるかどうかを示します。変数は変更されましたが、スピナーはまだ表示されます

class Scorer extends Component { 

    constructor(props, context) { 
     super(props, context); 

     this.store  =  this.context.store; 
     this.state  = { 
      matchId: props.match.params.id, 
      isLoading: true, 
      isSaving: false, 
      saveStatus: "", 
     }; 

     this.toggleSavingStatus = this.toggleSavingStatus.bind(this); 
     this.toggleLoadingStatus = this.toggleLoadingStatus.bind(this); 
    } 

    componentDidMount() { 
     // Get initial state from server 
     console.log('Get Initial State from Server', this.state.isLoading); 
     utilGetJSON('startup.php?matchId=' + this.state.matchId) 
      .then((response) => { 
       this.toggleLoadingStatus(); 

       this.store.dispatch({ 
        type:  constants.INITIAL_STATE, 
        payload: response.data 
       }); 
      }) 
      .catch((error) => { 
       console.log('axios.get ERROR', error); 
       this.toggleLoadingStatus(); 
      }); 
    } 


    toggleLoadingStatus() { 
     this.setState = ({ 
      isLoading: !this.state.isLoading, 
     },()=>{ 
      console.log('Flag toggle Loading: ', this.state.isLoading); 
     }); 
    } 
    toggleSavingStatus() { 

     this.setState = ({ 
      isSaving: !this.state.isSaving, 
     },()=>{ 
      console.log('Flag toggle Saving:', this.state.isSaving); 
     }); 
    } 

    componentWillReceiveProps(nextProps, nextState){ 
     saveStateToServer(nextState.store.getState(), this.toggleSavingStatus); 
     const stateSavedObj = getStateSavedObj(nextState.store.getState()); 

     if (stateSavedObj !== null){ 
      const lastSavedDate = new Date(stateSavedObj.timestamp * 1000); 
      this.setState({ 
       saveStatus: "Match last saved on server at "+lastSavedDate.toLocaleString() 
      }); 
     } 
    } 

    render() { 
     return (
      <div> 
       { this.state.isLoading && 
        <div className="text-center text-danger"> 
         <i className="fa fa-spinner fa-spin font-md" aria-hidden="true"></i><br/>Loading</div> 
       } 
       { this.state.isSaving && 
       <div className="text-center text-danger"> 
        <i className="fa fa-spinner fa-spin font-md" aria-hidden="true"></i><br/>Saving on server</div> 
       } 
       { this.state.saveStatus !== '' && !this.state.isSaving && 
       <div className="container"> 
        <div className="bs-callout bs-callout-danger text-danger"> 
         {this.state.saveStatus} 
        </div> 
       </div> 
       } 
      </div> 
     ); 
    } 
} 

Scorer.contextTypes = { 
    store: PropTypes.object 
}; 

私はシンプルために、このクラスが低下しています。 今度は、フラグをFALSEに設定する他の関数を呼び出します。 Console.logはそれを確認しますが、まだスピナーが表示されています。

Get Initial State from Server true 
Scorer.js:53 toggleLoadingStatus() called 
Scorer.js:57 Flag toggle Loading: true 

私は理解しません。私はいつも働いていました。変数をfalseに設定するだけでスピナーを簡単に隠すことができます。

助けてください。 、

class Scorer extends Component { 

    constructor(props, context) { 
     super(props, context); 
     this.state = { 
      isSaving: false 
     } 
     this.toggleSavingStatus = this.toggleSavingStatus.bind(this); 
    } 

    toggleSavingStatus() { 
     this.setState({ 
      isSaving : !this.state.isSaving 
     },()=>{ 
      console.log('Flag toggle', this.state.isSaving); 
     }); 
    } 

    render() { 
     return (
      <div> 
       <ScoreAction /> 
       { this.state.isSaving && 
       <div className="text-center text-danger"> 
        <i className="fa fa-spinner fa-spin font-md" aria-hidden="true"></i><br/>Saving on server</div> 
       } 
      </div> 
     ); 
    } 
} 

一つの最終編集、新しい更新された状態の値を確認するためにsetStateのコールバック関数を使用することをお勧め:

おかげ

答えて

2

では、あなたのコードは、そのようになっているはずのコンポーネントの状態を使用する必要がありますリアクト場合によっては、setStateという機能が非同期であるため、古い状態をログに記録することがあるためです。

+0

ご返信ありがとうございます。私はほとんどのクラスで州を使用しましたが、ここでは変数を使用したと思います。だから私は決してこれのような反応で変数を使うべきではありませんか?ただ状態? – Sallu

+0

はい、反応はコンポーネントの状態に依存するため、更新またはレンダリングのタイミングを知る必要があります。常にstateを使用し、setState関数を使用してコンポーネントの状態を更新する必要があります。 state.isSaving =!this.state.isSaving代わりにthis.setState({isSaving:!this.state.isSaving}) –

+0

私はすべての変数を状態に移動すると、このエラーは、アプリケーションのinstの開始時に取得します。 setState.bindは関数ではありません.'と 'axios.get ERROR TypeError:this.setStateは関数ではありません。 ' – Sallu

0

isSavingはクラス変数で、その値を変更してもrerenderがトリガーされません。この値を州のままにしておくことをお勧めします。setState

class Scorer extends Component { 

    constructor(props, context) { 
     super(props, context); 

     this.state = {isSaving:false} 
     this.toggleSavingStatus = this.toggleSavingStatus.bind(this); 
    } 

    toggleSavingStatus() { 
     this.setState((prevState) => ({isSaving: !prevState.isSaving})) 
    } 

    render() { 
     return (
      <div> 
       <ScoreAction /> 
       { this.isSaving && 
       <div className="text-center text-danger"> 
        <i className="fa fa-spinner fa-spin font-md" aria-hidden="true"></i><br/>Saving on server</div> 
       } 
      </div> 
     ); 
    } 
} 

問題あなたは、それがループに行くので、レンダリングからその値を変更するまでの状態で値を保つことがありません。そのような場合は、変数に保存しておき、毎回変更する必要がないときにforceUpdateを実行することができます。

+0

@Amr関数を正しくバインドする必要があります –

+0

setStateを使用していますが、まだ動作していません。残念ながら – Sallu

+0

正確に動作しないもの –

関連する問題