2016-07-23 164 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')); 

這些途徑可以單擊的選項卡(如圖所示一個例子):

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

... 

在我的渲染方法displayQuestions,我做了檢查

if (!questions) { 
    Loading content 
} 

return (
    {this.renderQuestions()} 
) 

所以,當用戶導航到頁面,在我的componentDidMount()中,我使用了一個動作方法this.props.fetchQuestions,然後它向我的後端發出異步請求,遍歷reducer,然後進入渲染方法abov即在renderQuestions函數中,在renderQuestions中,我只是從this.props.questions中獲取問題。

但是,我配置路由的方式,componentDidMount只發生一次。例如,如果我在英文選項卡上選擇,我會得到componentDidMount,但是如果我點擊數學或科學,url會更改,但componentDidMount不會再被調用。

如果我點擊一個按鈕,它使用了一個不同的組件,比如userProfile,那麼所有的事情都會按照預期的方式發生。但我認爲,因爲我在每個問題/主題路徑中使用相同的組件,所以componentDidMount不會再被調用。

那麼如何更新url更改的狀態?什麼是React + Redux方式?沒有反模式,請。

編輯:

現在,我來這個答案:

 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。略做取一個方法,並從他們兩人的調用它:

<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); 
    } 
} 
相關問題