在成功asynchronous还原操作时转换到另一个path

我有一个非常简单的反应组件:

  • container挂钩到redux并处理动作,存储订阅等
  • list显示我的项目列表
  • new ,这是一个新的项目添加到列表的forms

我有一些反应路由器路由如下:

 <Route name='products' path='products' handler={ProductsContainer}> <Route name='productNew' path='new' handler={ProductNew} /> <DefaultRoute handler={ProductsList} /> </Route> 

以便显示listform ,但不能同时显示。

我想要做的是让一个新项目成功添加后,应用程序重新路由回列表。

我到目前为止的解决scheme是在asynchronousdispatch之后有一个.then()

 dispatch(actions.addProduct(product) .then(this.transitionTo('products')) ) 

这是这样做的正确的方法,或者我应该发起另一个行动,以触发路线改变?

如果你不想使用像Redux Router这样更完整的解决scheme,你可以使用Redux History Transitions来编写这样的代码:

 export function login() { return { type: LOGGED_IN, payload: { userId: 123 } meta: { transition: (state, action) => ({ path: `/logged-in/${action.payload.userId}`, query: { some: 'queryParam' }, state: { some: 'state' } }) } }; } 

这与你所build议的类似,但稍微复杂一点。 它仍然使用相同的历史库,所以它与React Router兼容。

我最终创build了一个超级简单的中间件,看起来像这样:

 import history from "../routes/history"; export default store => next => action => { if ( ! action.redirect ) return next(action); history.replaceState(null, action.redirect); } 

所以从那里你只需要确保你的successful行动有一个redirect属性。 还要注意,这个中间件不会触发next() 。 这是有目的的,因为路线过渡应该是行动链的结束。

对于那些正在使用中间件API层来抽象类似于同形获取 ( isomorphic-fetch)的用法的用户来说,也可能会使用redux-thunk ,您可以简单地将您的dispatch Promise链接到您的动作中,如下所示:

 import { push } from 'react-router-redux'; const USER_ID = // imported from JWT; function fetchUser(primaryKey, opts) { // this prepares object for the API middleware } // this can be called from your container export function updateUser(payload, redirectUrl) { var opts = { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }; return (dispatch) => { return dispatch(fetchUser(USER_ID, opts)) .then((action) => { if (action.type === ActionTypes.USER_SUCCESS) { dispatch(push(redirectUrl)); } }); }; } 

这样就减less了将代码库添加到您的代码中的需求,同时也很好地将您的操作与redirect放在一起,就像在redux-history-transitions中所做的那样。

这是我的商店的样子:

 import { createStore, applyMiddleware } from 'redux'; import rootReducer from '../reducers'; import thunk from 'redux-thunk'; import api from '../middleware/api'; import { routerMiddleware } from 'react-router-redux'; export default function configureStore(initialState, browserHistory) { const store = createStore( rootReducer, initialState, applyMiddleware(thunk, api, routerMiddleware(browserHistory)) ); return store; } 

我知道我在派对上迟了一点,因为react-navigation已经包含在react-native文档中,但对于在其应用程序中使用/使用Navigator API的用户来说,它仍然是有用的。 我所尝试的是一点点的黑客,我一旦renderScene发生,就将对象导航器实例保存在对象中,

 renderScene(route, navigator) { const Component = Routes[route.Name] api.updateNavigator(navigator); //will allow us to access navigator anywhere within the app return <Component route={route} navigator={navigator} data={route.data}/> } 

我的api文件是这样的东西

 'use strict'; //this file includes all my global functions import React, {Component} from 'react'; import {Linking, Alert, NetInfo, Platform} from 'react-native'; var api = { navigator, isAndroid(){ return (Platform.OS === 'android'); }, updateNavigator(_navigator){ if(_navigator) this.navigator = _navigator; }, } module.exports = api; 

现在在你的行动,你可以简单地打电话

api.navigator.push({Name:'routeName',data:WHATEVER_YOU_WANTED_TO_PASS)

你只需要从模块导入你的api。