javascript-在异步redux操作成功后过渡到另一条路由

我有一组非常简单的react组件:

  • .then()挂接到redux并处理操作,存储订阅等
  • .then()显示我的项目列表
  • .then()是一种将新项目添加到列表的表单

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

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

因此显示的是.then()dispatch,但未同时显示。

我想做的是,一旦成功添加了新项目,就使应用程序重新路由回列表。

到目前为止,我的解决方案是在异步dispatch之后使用.then()

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

这是执行此操作的正确方法,还是我应该以其他方式触发其他操作以触发路线更改?

Clarkie asked 2019-11-05T21:30:18Z
5个解决方案
28 votes

如果您不想使用像Redux Router这样的更完整的解决方案,则可以使用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'
        }
      })
    }
  };
}

这与您的建议相似,但稍微复杂一点。 它仍然在后台使用相同的历史记录库,因此与React Router兼容。

Dan Abramov answered 2019-11-05T21:30:43Z
25 votes

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

import history from "../routes/history";

export default store => next => action => {

    if ( ! action.redirect ) return next(action);

    history.replaceState(null, action.redirect);
}

因此,从那里您只需要确保您的successful操作具有redirect属性。 另请注意,此中间件不会触发next()。这是有意为之的,因为路由转换应该是操作链的末尾。

silkAdmin answered 2019-11-05T21:31:15Z
18 votes

对于那些正在使用中间件API层来抽象化其同构提取等用法的应用程序,同时又碰巧使用redux-thunk的用户,您可以在操作内部简单地将dispatch链结在一起,如下所示:

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));
                }
            });
    };
}

这样可以减少如此处建议的向代码中添加库的需求,并且可以很好地将您的操作及其重定向(如在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;
}
Cameron answered 2019-11-05T21:31:53Z
0 votes

我知道我参加聚会不太晚,因为react-native文档已经包含了react-navigation,但是对于在其应用中使用/使用过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',   数据:WHATEVER_YOU_WANTED_TO_PASS)

您只需要从模块导入api。

Manjeet Singh answered 2019-11-05T21:32:44Z
0 votes

如果您使用的是react-redux和react-router,那么我认为此链接提供了一个很好的解决方案。

这是我使用的步骤:

  • 通过在React-Router history.push(to)组件内部渲染组件或使用to创建高阶组件,将react-router history道具传递到您的组件。
  • 接下来,创建您要重定向到的路由(我叫我history.push(to))。
  • 第三,同时使用history.push(to)to调用redux操作。
  • 最后,当您要重定向时(例如,您的redux操作解决时),请致电history.push(to)
Brad W answered 2019-11-05T21:33:41Z
translate from https://stackoverflow.com:/questions/32612418/transition-to-another-route-on-successful-async-redux-action