使用React Redux更新路由更改状态

时间:2016-07-23 01:26:57

标签: reactjs redux react-router react-redux react-router-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,然后它向我的后端发出异步请求,通过reducers然后进入渲染上面的方法。在renderQuestions函数中,在renderQuestions中,我只是从this.props.questions中获取问题。

但是,我配置路由的方式,componentDidMount只出现一次。例如,如果我在英文选项卡上选择,我会得到componentDidMount,但是如果我然后点击数学或科学,则网址会更改,但不会再次调用componentDidMount。

如果我点击了一个按钮,它使用了另一个组件,比如userProfile,那么所有内容都会按预期重新呈现。但我认为,因为我在每个问题/主题路径中使用相同的组件,所以不会再次调用componentDidMount。

那么如何更新网址更改的状态?什么是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;
      }

这会停止原本会发生的无限循环。但必须有更好的方法。

2 个答案:

答案 0 :(得分:1)

我不知道组件的确切布局,但听起来像“Tabs”组件都是一次安装一个组件。如果是这种情况,那么可能有一些州控制哪个标签显示正确?然后,您可以在componentWillReceiveProps中检查道具何时更改为问题标签。如果它已经执行了异步请求。

例如

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

答案 1 :(得分:1)

链接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);
    }
}