使用React Redux更新路由更改状态
我正在使用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;
}
这将阻止可能发生的无限循环。但是一定有更好的办法。
我不知道组件的确切布局,但听起来好像您的“选项卡”组件都是一次安装的组件。如果是这样,那么可能有一些状态控制哪个标签显示正确?当您的道具更改为问题标签时,您可以在componentWillReceiveProps
中进行检查。如果它有,然后做你的异步请求。
例如
componentWillReceiveProps(nextProps) {
if (nextProps.tab === 'questionTab' && this.props.tab !== 'questionTab') {
this.props.fetchQuestions();
}
}
链路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);
}
}
我不知道这件事,但我认为你应该做它componentWillReceiveProps –