在异步还原操作成功时转换到另一个路由
Transition to another route on successful async redux action
我有一组非常简单的react组件:
-
container
,钩子到redux和处理动作,存储订阅等 -
list
显示我的项目列表 -
new
,这是一个窗体添加一个新的项目到列表
我有一些反应路由器路由如下:
<Route name='products' path='products' handler={ProductsContainer}>
<Route name='productNew' path='new' handler={ProductNew} />
<DefaultRoute handler={ProductsList} />
</Route>
使list
或form
显示,但不同时显示。
我想做的是让应用程序在成功添加新项目后重新路由回列表。
到目前为止,我的解决方案是在异步dispatch
之后有一个.then()
:
dispatch(actions.addProduct(product)
.then(this.transitionTo('products'))
)
这是正确的方法,还是我应该触发另一个动作以触发路由更改?
如果你不想使用像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路由器兼容。
我最终创建了一个超级简单的中间件,大致看起来像这样:
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层来抽象他们的使用,比如同构提取,并且碰巧使用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;
}
我知道我有点晚了,因为react-navigation已经包含在react-native文档中,但它仍然可以为那些在他们的应用程序中使用/使用Navigator api的用户提供帮助。我所尝试的是小hackish,我保存导航实例在对象一旦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
如果你正在使用react-redux和react-router,那么我认为这个链接提供了一个很好的解决方案。
下面是我使用的步骤:- 传递一个react-router
history
prop给你的组件,要么在react-router<Route/>
组件中渲染你的组件,要么用withRouter
创建一个高阶组件。 接下来,创建你想重定向到的路由(我叫我的 - 第三,用
history
和to
调用你的redux动作。 - 最后,当你想要重定向时(例如,当你的redux动作解析时),调用
history.push(to)
。
to
)。- 如何在javascript转换编码中将一个动态值从一个表单添加到另一个页面
- 变量转换为另一个“未定义”的变量
- 将阵列转换为另一个阵列
- Addeventlistener 已转换为 IE.也许是另一个错误
- querySelectorAll()从另一个页面转换为html
- 如何在Ember中转换到另一个路由时调用一个方法
- 转换一个时间(字符串),例如1:00 IST到另一个时区(比如PST)
- 如何在angularjs中将一个具有赋值的指令转换为另一个指令
- 是否可以将一个DOM元素转换为另一个?或者从中复制所有属性
- 如何将某些HTML从一个页面转换为另一个表单
- 如何在javascript中将一个数组中的某些部分转换为另一个字符
- 如何在d3.js中将一个形状转换为另一个形状
- 从一个HTML转换到另一个HTML
- 将特定的机密 6 位数字转换为另一个 6 位数字
- 将 JavaScript Date 从一个时区转换为另一个时区
- Javascript Cryptography - 将一个字符转换为另一个字符
- 将鼠标坐标从一个窗口大小转换为另一个窗口尺寸
- 将mouseup函数转换为另一个函数,并在jQueryUI滑块中使用它
- 事件侦听器,一个css转换结束,另一个开始
- 如何将一个JSON对象转换为另一个JSON object