我来自Angular并习惯了ui-router的解析功能,这使得等待并将结果注入控制器变得容易。
目前,我希望通过反应来模仿这一点,而无需在使用React Router时在componentWillMount
方法中编写请求(或触发操作)。我认为有一种更好的方法可以做到这一点,我只是没想出来。
希望得到一些建议或指出我可以学习的地方
答案 0 :(得分:11)
最好的办法是在Router.run
(http://rackt.github.io/react-router/#Router.run)中使用回调。你传递给它的回调会在url发生变化时被调用,并且它负责重新渲染,就像这个从页面中获取的例子一样:
Router.run(routes, function (Root) {
// whenever the url changes, this callback is called again
React.render(<Root/>, document.body);
});
在该函数中,您可以在调用React.render()
之前执行所需的任何异步操作,如下所示:
Router.run(routes, function (Root) {
// whenever the url changes, this callback is called again
asyncStuff().then(function (data) {
React.render(<Root data={data} />, document.body);
});
});
这种方法的问题在于,在数据可用之前,您的UI根本不会做出反应。相反,我建议使用空状态渲染组件,并在componentDidMount
中获取数据,然后在数据进入时重新渲染。或者更好的是,将数据提取和渲染分成两个组件。一个组件获取数据,并将其作为属性传递给呈现组件。数据获取组件甚至可以避免渲染其他组件,除非数据存在,例如:
render: function () {
if (this.state.data) {
return <TheComponent data={this.state.data} />;
} else {
return <Spinner />;
}
}
这是React中的常见模式,用于分隔处理数据获取和状态的组件,以及呈现该状态的组件。您希望尽可能将有状态组件推送到层次结构中,因为它会创建逻辑边界。有状态的组件是90%的错误发生的地方,当你捕获bug时能够专注于那些错误是很好的。
等待的另一个问题是用户可能会快速导航,这意味着在第一个数据进入之前会再次调用Router.run
回调。所以你需要确保中止最后一个操作而不是渲染一点都不。