我有一套非常简单的反应组件:
container
挂钩到redux并处理操作,存储订阅等list
显示我的项目列表new
这是一个将新项目添加到列表中的表单我有一些react-router路线如下:
<Route name='products' path='products' handler={ProductsContainer}>
<Route name='productNew' path='new' handler={ProductNew} />
<DefaultRoute handler={ProductsList} />
</Route>
以便显示list
或form
,但不能同时显示。{/ p>
我想做的是在成功添加新项目后让应用程序重新路由到列表。
到目前为止,我的解决方案是在异步.then()
后有一个dispatch
:
dispatch(actions.addProduct(product)
.then(this.transitionTo('products'))
)
这是正确的方法吗?还是我应该以某种方式触发另一个动作来触发路线改变?
答案 0 :(得分:28)
如果您不想使用更完整的解决方案,例如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'
}
})
}
};
}
这与what you suggested类似,但稍微复杂一点。它仍然使用相同的history库,因此它与React Router兼容。
答案 1 :(得分:25)
我最终创建了一个非常简单的中间件,看起来很像:
import history from "../routes/history";
export default store => next => action => {
if ( ! action.redirect ) return next(action);
history.replaceState(null, action.redirect);
}
因此,您需要确保successful
行为具有redirect
属性。另请注意,此中间件不会触发next()
。这是有目的的,因为路线转换应该是行动链的终点。
答案 2 :(得分:18)
对于那些使用中间件API层来抽象使用isomorphic-fetch之类的人,并且碰巧使用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));
}
});
};
}
这减少了按照建议here将代码库添加到代码中的需要,并且很好地将您的操作与其重定向放在一起,如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;
}
答案 3 :(得分:0)
我知道我在派对上已经很晚了,因为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文件是lke this
'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({名称: 'routeName', 数据:WHATEVER_YOU_WANTED_TO_PASS)
你只需要从模块导入你的api。
答案 4 :(得分:0)
如果您使用的是react-redux和react-router,那么我认为this link提供了一个很好的解决方案。
这是我使用的步骤:
conda
组件内部渲染组件或使用history
创建高阶组件,将React-Router <Route/>
道具传递给组件。 / li>
withRouter
)。to
和history
来调用redux动作。to
。