2016-10-10 8 views
1

私はそうのように見えるReduxのサンクを使用するアクション、持っている:Reduxの:再利用可能なアクション

export function fetchData(query) { 
    return dispatch => { 
    return fetch(`http://myapi?query=${query}` ,{mode: 'cors'}) 
     .then(response => response.json()) 
     .then(json => { dispatch(someOtherAction(json)) }) 
    } 
    } 
} 

をして、私のsomeOtherActionが実際に状態を更新します。

export function someOtherAction(data) { 
    return { 
     action: types.SOME_ACTION, 
     data 
    } 
} 

しかし、私はそれをしたいですfetchDataアクションクリエーターを再利用できるようにして、アプリのさまざまな部分がmyapiからデータを取得し、それに基づいて状態の異なる部分を持つようにすることができます。

このアクションを再利用する最良の方法は何ですか?フェッチ成功に呼ばれて、それがどのアクションを規定している私のfetchDataアクションの作成者への2番目のパラメータを渡すことが可能です:

export function fetchData(query, nextAction) { 
    return dispatch => { 
    return fetch(`http://myapi?query=${query}` ,{mode: 'cors'}) 
     .then(response => response.json()) 
     .then(json => { dispatch(nextAction(json)) }) 
    } 
    } 
} 

するか、この種のものを行うための受け入れられた方法はありますか?

+0

アクションに追加の引数を渡すことはできません。 –

+0

私は非常によく似たハッキン​​グをしています。また、 '' fetchData''の追加引数として '' nextErrorAction''を行います。さらに、状態コードが2xxで、 '' dispatch(nextErrorAction(data)) ''と '' reject''のときに '' resolve''と一緒に '' dispatch(nextAction(data)) ''と '' dispatch 4xx/5xx用。それは非常にうまく動作し、ちょうど数行のコードです。 – iamnat

+0

ああ、それは面白いです。追加のパラメータを渡す必要があるかどうかについては、ドキュメントを見つけることができません。私は行動を全く取っておく必要はないと思っていますか? https://github.com/gaearon/redux-thunkは、アクションクリエータの外部でフェッチを行う 'fetchSecretSauce'メソッドを定義しています。 –

答えて

1

私はミドルウェアを使用しています。私はフェッチ呼び出しを定義しています。そして、私のアクションでは、フェッチするURLと完了時にディスパッチするアクションを送信します。これは典型的なアクションをフェッチ次のようになります。そのアクションを呼び出すとき

const POSTS_LOAD = 'myapp/POST_L'; 
const POST_SUCCESS = 'myapp/POST_S'; 
const POST_FAIL = 'myapp/POST_F'; 

export function fetchLatestPosts(page) { 
    return { 
    actions: [POSTS_LOAD, POST_SUCCESS, POST_FAIL], 
    promise: { 
     url: '/some/path/to/posts', 
     params: { ... }, 
     headers: { ... }, 
    }, 
    }; 
} 

POST_LOADアクションはちょうどそれが実行されますフェッチ要求の前にミドルウェアによって自動的にディスパッチされます。すべてがうまくいけば、POST_SUCCESSアクションがjsonレスポンスでディスパッチされます。何か問題が生じた場合は、POST_FAILアクションがミドルウェアによってディスパッチされます。

すべての魔法はミドルウェアにあります!

export default function fetchMiddleware() { 
    return ({ dispatch, getState }) => { 
    return next => action => { 
     if (typeof action === 'function') { 
     return action(dispatch, getState); 
     } 

     const { promise, actions, ...rest } = action; 

     if (!promise) { 
     return next(action); 
     } 

     const [REQUEST, SUCCESS, FAILURE] = actions; 
     next({ ...rest, type: REQUEST }); // <-- dispatch the LOAD action 


     const actionPromise = fetch(promise.url, promise); // <-- Make sure to add the domain 

     actionPromise 
     .then(response => response.json()) 
     .then(json => next({ ...rest, json, type: SUCCESS })) // <-- Dispatch the success action 
     .catch(error => next({ ...rest, error, type: FAILURE })); // <-- Dispatch the failure action 

     return actionPromise; 
    }; 
    }; 
} 

私は、単一の場所にすべての私の要求を持っていると私はそれが終了の要求後に実行するアクションを定義することができますこの方法:そしてそれは、これに似たようなのです。

------------ EDIT ----------------

減速上のデータを取得するためには、あなた元のアクション作成者に定義したアクション名を使用する必要があります。次の例は、アクションをミドルウェアから処理してpostsデータをjsonレスポンスから取得する方法を示しています。

export function reducer(state = {}, action) { 
    switch(action.type) { 
    case POST_SUCCESS: // <-- Action name 
     return { 
     ...state, 
     posts: action.json.posts, // <-- Getting the data from the action 
     } 
    default: 
     return state; 
    } 
} 

私はこれが役立つことを望みます。

+0

回答ありがとう@crysfel。一つの質問。 POST_LOAD、POST_SUCCESSとは何ですか?それはアクションクリエーター関数か、タイプとアクションを持つオブジェクトです。どんなアクションがそこにあるのかの例を追加できますか? –

+1

これは単にアクション名です: 'const POSTS_LOAD = 'myapp/POST_L';'あなたはレデューサーでこれを受け取ろうとしています。この名前に基づいて、あなたはデータまたはあなたの状態で何をしたいかを行います。私は減速機の例を追加しました。 – Crysfel

+0

申し訳ありません、前を無視してください。私は自分のコードに愚かな間違いがありました。ご協力いただきありがとうございます。私はここでたくさんのことを学びましたが、今でも私自身のreduxミドルウェアを作成することでスピードアップしています。 –

関連する問題