4

我正在使用 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,然后它向我的后端发出异步请求,通过减速器,然后进入上面的渲染方法。在 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;
      }

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

4

2 回答 2

1

Link to 属性可以接收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);
    }
}
于 2016-07-23T14:53:53.690 回答
1

我不知道您的组件的确切布局,但听起来您的“Tabs”组件都是一个安装一次的组件。如果是这种情况,那么可能有一些状态可以控制显示哪个选项卡?然后,您可以检查componentWillReceiveProps道具何时更改为问题选项卡。如果它有那么做你的异步请求。

例如

componentWillReceiveProps(nextProps) {
  if (nextProps.tab === 'questionTab' && this.props.tab !== 'questionTab' ) {
    this.props.fetchQuestions();
  }
}
于 2016-07-23T04:20:48.150 回答