2016-07-23 166 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); 
    } 
} 
相关问题