成功执行异步redux操作后转换到另一个路由

Cla*_*kie 57 javascript reactjs react-router redux

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

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

我有一些react-router路由如下:

<Route name='products' path='products' handler={ProductsContainer}>
  <Route name='productNew' path='new' handler={ProductNew} />
  <DefaultRoute handler={ProductsList} />
</Route>
Run Code Online (Sandbox Code Playgroud)

所以显示listform显示,但不是两者.

我想做的是在成功添加新项目后让应用程序重新路由回列表.

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

dispatch(actions.addProduct(product)
  .then(this.transitionTo('products'))
)
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?或者我应该以某种方式触发另一个动作来触发路线改变?

Dan*_*mov 28

如果您不想使用Redux路由器等更完整的解决方案,可以使用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'
        }
      })
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

这与你的建议相似,但稍微复杂一点.它仍然使用相同的历史库,因此它与React Router兼容.


sil*_*min 25

我最终创建了一个非常简单的中间件,看起来很像:

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

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

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

    history.replaceState(null, action.redirect);
}
Run Code Online (Sandbox Code Playgroud)

所以,从那里你只需要确保你的successful行为有一个redirect属性.另请注意,此中间件不会触发next().这是有目的的,因为路径转换应该是动作链的结束.


Cam*_*ron 18

对于那些使用中间件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));
                }
            });
    };
}
Run Code Online (Sandbox Code Playgroud)

这减少了在此处建议将代码库添加到代码中的需要,并且很好地将您的操作与其重定向一起定位,如在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;
}
Run Code Online (Sandbox Code Playgroud)

  • 不正常工作url被重定向,但我在页面中的内容不会改变..即使更改网址,它也显示相同的页面.. (2认同)
  • 对于像我这样想知道函数 `push` 来自哪里的人: `import { push } from 'react-router-redux'` (2认同)