2017-07-10 6 views
0

私はAPIコール用のredux-apiミドルウェアと副作用のためのredux-sagasを使用しています。特定のフォームフローの場合、ユーザーは2つの異なる変更を行うことができ、別々のapiで処理する必要があります。そして、もし彼らの1人が失敗すれば、サガ全体が失敗するはずです。私は失敗を扱う別々のサガを持っています。 場合によっては、これが壊れます。デベロッパーツールを見ると、サガは2回実行され、最初のステップにジャンプしてから、再びステップを実行します。私はこれをコメントとしてマークしました。redux-sagasで 'take'を使って進行を待つことはできますか?佐賀のフローは、そのように使用されるとサガの前のポイントに戻る

function* saveFormChanges(action) { 
    // point (1) 
    if (action.changesA) { 
    yield put(changesAApi()); 
    // jumps to point (1) the first time 
    yield take('changes-A-success'); 
    // point (2) 
    } 
    if (action.changesB) { 
    yield put(changesBApi()); 
    // jumps to point (2) 
    yield take('changes-B-success'); 
    // point (3) 
    } 
    // jumps to point (3) 
    yield call(displaySuccessMessage); 
} 

function* errorSaga() { 
    yield takeLatest(action => /failure$/.test(action.type),() => { 
    alert('failure'); 
    }); 
} 

はこれです -

アクション - -

function changesAApi() { 
    return (dispatch, getState) => { 
    dispatch({ 
     [CALL_API]: { 
     types: ['changes-A', 'changes-A-success','changes-A-failure'], 
     endpoint: '/changesA', 
     method: 'post', 
     } 
    }) 
    } 
} 

// can be called individually, but state in A affects this call 
function changesBApi() { 
    return (dispatch, getState) => { 
    dispatch({ 
     [CALL_API]: { 
     types: ['changes-B', 'changes-B-success','changes-B-failure'], 
     endpoint: '/changesB', 
     method: 'post', 
     } 
    }) 
    } 
} 

サガサガをトリガーアクションのthatsは一度だけ

ここでモックコードだ(Reduxの開発ツールで検証)を実行していますこの流れを作る正しい方法は?これを行うより良い方法はありますか?

答えて

0

正直なところ、私はこれを全く異なる方法で構造化します。私には、問題は多すぎるようです。簡単な解決策は、どちらか一方を使用することです。個人的には、私は自分のAPIがどのように消費されるかをより詳細に制御できるので、私はすべてのAPI呼び出しにsagasを使用するのが好きです。

サガースのドキュメントはサガースの基本的な例を示しています。これはすごく素敵なチュートリアルです。私はthe proper way to compose sagasについて覚えていれば、サガはそれほど制限されていないことがわかりました。

このようにサガを作成すると、非同期の状態変更をはるかにエレガントな方法で処理でき、コードの可読性が大幅に向上します。

これは私が一緒にあなたの問題のための1つの可能な解決策を示す置く速い少し抜粋です:

// dispatch from component 
const getUsers =() => dispatch({type: 'GET_USERS'}) 

function* watchGetUsers() { 

    while(true) { 
     try{ 
      yield take('GET_USERS') 
      yield put({ type: 'REQUEST/GET_USERS' }) 

      const data = yield call(methodThatCallsAPI, args) 
      // side effects stuff 
      yield put({ type: 'SUCCESS/GET_USERS', payload: data}) 
      // redux reducer handles changing state 
     } catch (err) { 
      yield put({ type: 'FAILURE/GET_USERS', payload: err }) 
      // redux reducer handles changin state 
      // coul also just use put to pass logic to error saga 
     } 

    } 
} 

あなたも行われたすべての同時要求をブロックするか、未完成のものをキャンセルするサガを使用することができます。これは、あなたのサーガをブロックする方法のもう1つの例です。

// put sagas into an object 
const apiSagas = { 
    'GET_USERS': watchGetusers, 
    // other sagas 
} 

function* consumeApiRequestsBlocking() { 
    while(true) { 
     // dispatch({ type: 'API_REQUEST', payload: {type: GET_USERS}}) 
     const request = yield take('API_REQUEST') 

     yield call(apiSagas[request.type]) 
     // 'API_REQUEST' cannot be dispatched until above line finishes 
     // since call is blocking; fork is non-blocking 

     // NOTE: you sould remove the yield take('GET_USERS') from 
     // watchgetUsers in this example 
    } 
} 

Good Luck!

関連する問題