反応コンポーネントの非常に単純なセットがあります。
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
のいずれかが表示されますが、両方は表示されません。
私がやりたいのは、新しいアイテムが正常に追加されたら、アプリケーションをリストに再ルーティングすることです。
これまでの私の解決策は、非同期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'
}
})
}
};
}
これは 提案したもの に似ていますが、少し洗練されています。まだ内部で同じ history ライブラリを使用しているため、React Routerと互換性があります。
私は最終的にそのように見える非常にシンプルなミドルウェアを作成することになりました:
_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
次のように、アクション内で約束します。
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;
}
反応ナビゲーションは既に反応ネイティブのドキュメントに含まれているので、私はパーティーに少し遅れていることを知っていますが、それでもアプリで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をインポートするだけです。
react-redux および react-router を使用している場合、 このリンク が優れたソリューションを提供すると思います。
私が使用した手順は次のとおりです。
<Route/>
_コンポーネント内にレンダリングするか、history
を使用して高次コンポーネントを作成することにより、反応ルーターwithRouter
propをコンポーネントに渡します。to
と呼びました)。history
とto
の両方でreduxアクションを呼び出します。history.Push(to)
を呼び出します。