2017-10-12 5 views
0

私は同じアクションタイプの複数のタスクの取り消しをredux-sagaに組み込む方法を見つけようとしています。基本的に、私のコンポーネントがcomponentWillUnmount()にあるとき、私はそれが開始したかもしれないすべてのタスクを取り消したいと思います。redux-saga:同じアクションタイプ/ sagaの複数のタスクをキャンセルする

私は、次のアクションを持っている場合(これは非常に私は実際に私のコードに持っているものから簡略化されているが、私は必需品にそれを削り取っしようとしている):

// Action 
export const loadMyData = params => { 
    let url = /* Create URL based on params */ 
    return { 
    type: FETCH_DATA, 
    url, 
    key: /* a unique key so we can retrieve it in the state later */ 
    } 
} 

そして、次のサガ:

// Saga 
export function* fetchData(action) { 
    try { 
    // 'callApi()' currently uses axios 
    let response = yield call(callApi, action.url); 

    yield put({ 
     type: FETCH_SUCCESS, 
     key: action.key, 
     payload: response.data 
    }); 
    } catch(error) { 
    yield put({ 
     type: FETCH_FAILURE, 
     error 
    }); 
    } 
} 

export function* watchFetchData() { 
    while (true) { 
    let action = yield take(FETCH_DATA); 
    let task = yield fork(fetchApi, action); 
    } 
} 

上記のように、コンポーネントはloadMyData()を複数回呼び出すことがあります。さらに、loadMyData()も呼び出す他のコンポーネントがあるかもしれません。だから、componentWillUnmount()状態にあるコンポーネントだけからタスクをキャンセルする方法を見つけようとしていますが、他の実行中のタスクはそのままにしておきます。

Redux Saga Cancellation documentationでは、その例は後で取り消しアクションが必要な単一のタスクです。そして私はそれを私のユースケースに拡張する方法を理解することができません。私の心に来る何

答えて

1

は以下の通りです:

registerWatchFetchData = (componentKey) => { 
    return { 
    type: "REGISTER_WATCH_FETCH_DATA", 
    payload: { componentKey } 
    } 
} 

減速:

// ... 
case "REGISTER_WATCH_FETCH_DATA": 
    return {...state, tasks: {...state.tasks, [action.payload.componentKey]: []}} 
componentWillMount

アクションを派遣し、そのように減速中にタスクを格納することによって、あなたのコンポーネントを登録します

function* watchFetchData()の中には、私が提供するcomponentKeyをキーとする対応するコンポーネントのレデューサーに新しいタスクが保存されます。 N​​:

export function* watchFetchData() { 
    while (true) { 
    let action = yield take(FETCH_DATA); 
    let task = yield fork(fetchApi, action); 
    yield put({ type: "STORE_TASK", payload: { componentKey: action.payload.componentKey, task } }) 
    } 
} 

はその後減速に

// ... 
case "STORE_TASK": 
    return {...state, tasks: {...state.tasks, [action.payload.componentKey]: [...state.tasks[action.payload.componentKey], action.payload.task]}} 

を追加しcomponentWillUnmountに、あなたは、componentKeyのすべてのタスクを引き出し、それらを反復処理し、同様にそれらをすべてキャンセルするサガを伝えるために別のアクションを派遣しますso:

function* watchUnregisterComponent(){ 
    while(true){ 
     const action = yield take("UNREGISTER_WATCH_FETCH_DATA") 
     const componentTasks = yield select(state => state.myReducer.tasks[action.payload.componentKey]) 
     componentTasks.forEach((t) => { 
      yield cancel(t) 
     }) 
     // dispatch another action to delete them from the reducer 
    } 
} 
関連する問題