在我当前的实现(下面)中,在渲染下一页之前更新存储.当当前页面根据下一页的数据获得商店更新时出现问题:(1)当前页面无意义地呈现(它订阅了商店更新),因为更新的商店用于下一页(2)渲染时的当前页面中断,因为更新的存储仅包含下一页的数据.
superagent .get(opts.path) .set('Accept','application/json') .end((err,res) => { let pageData = res && res.body || {}; store.dispatch(setPageStore(pageData)); render(store); });
反过来也有问题,在更新商店之前渲染下一页.现在的问题是渲染的下一个分页符,因为在更新存储之前,下一页所需的数据不存在.
我要么滥用这些库,要么我的架构不完整,或其他什么.救命!
其余的示例代码:
应用
const React = require('react'); const Router = require('react-router'); const {createStore} = require('redux'); const {update} = React.addons; const routes = require('./routes'); // all the routes let store = {}; let initialLoad = true; Router.run(routes,Router.HistoryLocation,(Handler,opts) => { if(initialLoad) { initialLoad = false; // hydrate const initialState = JSON.parse(document.getElementById('initial-state').text); store = createStore(appReducer,initialState); render(store); } else { superagent .get(opts.path) .set('Accept','application/json') .end((err,res) => { let pageData = res && res.body || {}; store.dispatch(setPageStore(pageData)); render(store); }); } }); function render(store) { React.render( <Provider store={store} children={() => <Handler/>} />,document.getElementById('react') ); }
动作&减速器
function appReducer(state = {},action) { switch(action.type) { case 'SET_PAGE_STORE': return update(state,{$merge: action.pageData}); default: return reduce(state,action); } } const reduce = combineReducers({ // ..all the reducers }); function setPageStore(pageData) { return {type: 'SET_PAGE_STORE',pageData}; }
redux-thunk
中间件一个接一个地分派多个操作
请参阅精彩redux doc #Async Actions section以获取更多信息!
所以你的fetch数据动作创建者看起来像这样:
function fetchSomeData(path) { return dispatch => { // first dispatch a action to start the spinner dispatch(fetchStarted(path)) return superagent.get(path) .set('Accept',res) => { if (err) { dispatch(fetchDataError(err)) // handle error } else { let pageData = res && res.body || {}; dispatch(fetchSuccess(pageData)); // do whatever you want when fetch is done here // such as this action from redux-simple-router to change route dispatch(pushPath('/some/path')) }); } }
正如您所看到的,通过简单地执行store.dispatch(fetchSomeData(‘somePath’)),它将自动首先调用fetchStarted来显示微调器,并且当进程完成时,调用fetchSuccess(path)来隐藏微调器,更新状态,重新渲染…等,或调用fetchError(错误)显示错误消息,您可以调用操作来在此过程中的任何位置更改路由!
(你不需要redux-simple路由器,如果你不喜欢它,你可以调用history.pushState(null,’/ some / path’)来改变路由,我刚发现redux-simple-router真的很方便,因为你不需要在任何地方传递历史记录,如果你想跟踪路线变化你还可以听到UPDATE_PATH动作)
此外,当您将react-router与redux一起使用时,我建议使用redux-simple-router
,它允许您使用UPDATE_PATH操作类型来监视路由更改,并使用pushPath操作来更改路由.
另外,我注意到你使用的是反应路由器的过时版本……
如果你想使用最新版本的react-router与redux-simple-router(连同redux-thunk),check out this repo!
你可以在这些文件中找到它的商店配置,路由器设置:
src/main.js // calls reactDOM.render(<Root />,...) to render <Root /> src/containers/Root.js // <Root /> is a wrapper for react-redux <Provider /> src/redux/configureStore.js // store configuration,how redux-thunk middleware is configured src/routes/index.js // routes are defined here