2016-07-23 48 views
4

React + Reduxを使用しており、状態を正しく更新する方法を知りたい。React Reduxによる経路変更の状態の更新

ReactDOM.render(
    <Provider store={store}> 
    <Router history={browserHistory}> 

     <Route path="/questions" component={App}> 
     <Route path="subject"> 
      <Route path="english" component={displayQuestions} /> 
      <Route path="math" component={displayQuestions} /> 
      <Route path="science" component={displayQuestions} /> 
      <Route path="history" component={displayQuestions} /> 
     </Route> 
     </Route> 

     ... 

    </Router> 
    </Provider> 
    , document.querySelector('.app')); 

これらのルートは(1例がここに示されている)タブでクリックすることができます。

<div> 
    <Link to={'/questions/english'}>English</Link> 
</div> 

... 

を私のrenderメソッドでdisplayQuestionsのために、私は

if (!questions) { 
    Loading content 
} 

return (
    {this.renderQuestions()} 
) 

だから、ときチェックを行いますユーザーがページにナビゲートし、私のcomponentDidMount()でアクションメソッドthis.props.fetchQuestionsを使用して、バックエンドに非同期要求を行い、レデューサーを経てレンダリングメソッドabovに移動しますe。 renderQuestions関数では、そしてrenderQuestionsではthis.props.questionsから質問を取得します。

ただし、ルートを設定した方法では、componentDidMountは1回だけ発生します。たとえば、英語のタブを選択した場合、componentDidMountが表示されますが、数学や科学をクリックするとurlは変わりますが、componentDidMountは再び呼び出されません。

ボタンを押すと、userProfileのような別のコンポーネントが使用され、すべてが期待どおりに再表示されます。しかし、私は各質問/科目のパスで同じコンポーネントを使用しているので、componentDidMountは再び呼び出されないと思います。

URL変更の状態を更新するにはどうすればよいですか? React + Reduxとは何ですか?反パターンはしないでください。

EDIT:今のところ

、私はこの答えになってきた:

 componentDidUpdate(nextProps) { 

     if (this.props.route.path !== nextProps.route.path) { 
      let subject = this.props.location.pathname.split('/')[3]; 
      this.props.fetchQuestions(subject); 
     } 

     return false; 
     } 

これは、そうでない場合に発生する無限ループを停止します。しかし、より良い方法が必要です。

+0

私はそれについてはよく分からないが、私はあなたがcomponentWillReceiveProps –

答えて

1

コンポーネントの正確なレイアウトはわかりませんが、「タブ」コンポーネントのように聞こえるのは、一度マウントされるコンポーネントのすべてです。そうであれば、おそらく、どのタブを右に表示するかを制御する状態がありますか?小道具が[質問]タブに変更された場合は、componentWillReceivePropsのチェックを行うことができます。そうであれば、非同期リクエストを行います。例えば

componentWillReceiveProps(nextProps) { 
    if (nextProps.tab === 'questionTab' && this.props.tab !== 'questionTab') { 
    this.props.fetchQuestions(); 
    } 
} 
+1

でそれをやるべきだと思う実際には、componentWillUpdateを使用すると、無限ループが発生します。更新時に、非同期要求が行われ、新しいムービーが返されたときにcomponentWillUPdateが呼び出され、無期限に続きます。 – jro

+0

ああ、私は、現在の小道具がまだ質問タブでない場合にチェックを追加するつもりです。そうすれば、 'fetchQuestions'は、タブが「質問」タブに変わったときにだけ呼び出されます。 – Jackson

+0

私はjroの提案にしたがって答えを編集しました。これは 'componentWillReceiveProps'を使うべきであり、' componentWillUpdate'を使うべきではないと思います。 – Grsmto

0

リンクto propertyについて

だけパス名の代わりにLocationDescriptorオブジェクトを受信することができます。場所記述子を使用すると、コンポーネントcomponentWillReceivePropsのメソッドをチェックインできる状態を渡すことができます。ただし、componentWillReceivePropsはコンポーネントのマウント時に呼び出されないため、コンポーネントがマウントされるときにもこの呼び出しを行う必要があります(componentWillMount)。より良いフェッチする1つの方法を作り、それらの両方からそれを呼び出す:

<div> 
    <Link to={ 
       pathname: '/questions/subject', 
       state: { subject: 'english'} 
    }>English</Link> 

    <Link to={ 
       pathname: '/questions/subject', 
       state: { subject: 'science'} 
    }>English</Link> 
</div> 

/** now you can declare only one route, and the state invokes the change **/ 
<Route path="/questions" component={App}> 
    <Route path="subject" component={displayQuestions} /> 
</Route> 

class displayQuestions extends React.Component { 
    _updateQuestions(props, nextProps) { 
      const currentSubject = props.location.state.subject; // the current subject 
      const nextSubject = nextProps ? nextProps.location.state.subject : null; // the nextSubject (componentWillReceiveProps) or null (componentWillMount) 
      if(currentSubject === nextProps) { // if the subjects are equal do nothing 
       return; 
      } 

      props.fetchQuestions(nextSubject || currentSubject); // fetch the questions of nextSubject (componentWillReceiveProps) or currentSubject (componentWillMount) 
    } 

    componentWillMount() { 
      _updateQuestions(this.props); 
    } 

    componentWillReceiveProps(nextProps) { 
      _updateQuestions(this.props, nextProps); 
    } 
} 
関連する問題