我正在尽力遵守 Flux 模式,但我一定错过了一些东西,因为我不知道如何在不使用 hack 或做一些对模式来说感觉错误的事情的情况下让它工作。
我有一个由大量数据分段的应用程序。假设它是一个资源管理应用程序,公司的每个部门都有一组不同的资源。该应用程序的用户将始终前往他们所属的任何部门,并留在那里。有些人可能管理多个部门。
因此,在此应用程序的顶部,将有一种方法可以选择您正在使用的部门。
这里的关键是,在加载部门列表并且选择要显示的部门(目前只是列表中的第一项)之前,我无法真正显示任何有用的内容。
为了实现此目的,应用程序的根组件会查看 DepartmentStore 以确定它当前是否正在加载。如果正在加载,它甚至不会渲染组件。像这样的事情:
function initApp(projectSlug) {
// prefetch some data!
DeptActions.getAll();
}
function getStateFromStores() {
return {
loading: DeptStore.getLoading()
};
}
export default React.createClass({
getInitialState: function() {
return getStateFromStores();
},
componentDidMount: function() {
initApp();
DeptStore.addChangeListener(this._deptChange);
},
componentWillUnmount: function() {
DeptStore.removeChangeListener(this._deptChange);
},
_deptChange: function() {
this.setState(getStateFromStores());
},
render: function() {
return (
this.state.projectsLoading
? <div>Loading...</div>
: (<div>
<Header/>
<div className="body-content">
<div className="grid-container">
{this.props.children}
</div>
</div>
<Footer/>
</div>)
);
}
});
props.children 将是 React Router 指定的任何组件。
这样,页面的实际组件就可以呈现并理所当然地认为所有部门都已加载,并且已经设置了“当前”部门。
问题是组件一旦渲染,就需要开始加载该部门的资源。为了开始该过程,它在安装时启动一个操作:
componentDidMount: function(){
ResourceActions.getResources();
},
此操作将启动 API 调用,该调用使用 DeptStore 的当前部门来了解要加载的内容。然后它调度 RESOURCE_LOADING 事件,也许您可以猜到,它失败了,因为:
Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
这是因为基本上,部门加载的操作会导致资源组件呈现,从而尝试启动资源获取操作。一项行动会导致另一项行动。
关于此类问题的所有示例和类似问题都不令我满意。例如:
Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch
a scenario flux doesn't support
即使是 Facebook 的待办事项列表和聊天应用程序示例也没有解决这个问题。待办事项列表甚至没有加载的“初始”数据。聊天应用程序可以,但它只是在应用程序启动时加载所有消息。
应用程序启动时我无法加载资源,因为我必须首先知道哪个部门。即使我以某种方式知道这一点,我也不想加载资源,除非资源组件需要它们。用户可能位于当前部门的其他页面上,这些页面不显示资源。因此,以某种方式加载资源以响应原始部门变更事件对我来说也是不可行的。
请帮助我获得解决此问题所缺少的见解? :) 如何将部门列表分开,然后加载资源以响应部门加载,并使其以某种方式由组件驱动,这样我就不会进行昂贵的资源 API 调用,除非页面上的组件需要它吗?
最佳答案
正如其他帖子中的答案所指出的,这是通量模式解决方案中的一个缺点/漏洞。唯一的解决方法(与之前的答案类似)是在顶部组件中创建来自 componentDidMount()
和 componentDidUpdate()
的调用,其功能如下:
checkAndFetchResources: function() {
if (this.props.resourcesToRender != undefined) {
ResourceActions.getResources();
}
}
并将获取的资源作为 props 传递给资源组件。 这样,您的获取操作就会在上一轮调度之后调用,然后渲染周期完全完成。
这与之前提供的答案类似,因此可能不足以满足您的需求(正如您在问题中所述)。在这种情况下,进一步澄清为什么答案不能满足您的需求将会有所帮助。
关于reactjs - 如何在 Flux 中加载初始数据,但前提是组件需要它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33114000/