2017-07-19 134 views
3

我只是實現了一個拖放功能與反應,免打擾,當用戶在我的應用程序丟棄SkyElement項目,我更新這反過來又更新了Redux店Redux updateElementSaga已被取消。爲什麼?

但是,更新調用服務器上的topleft偶爾工作,而不是每次。在我的控制檯中,我看到一個警告; updateElementSaga has been cancelled

在我SlotView.js,在一個功能,我有:

this.props.dispatch(requestUpdateElement({ id, top, left }));

在我elements/actions.js

export function requestUpdateElement(element) { 
    return { type: 'requestUpdateElement', element }; 
} 

在我elements/sagas.js

export function *updateElementSaga(action) { 
    const response = yield call(api.updateElement, action.element); 

    if (response.element) { 
     // debugger; // this hits, saga was cancelled will have appeared in the console at this point 
     yield put(actions.receiveElement(response.element)); 
    } else if (response.error) { 
     console.log('error receiving element'); 
    } 
} 

export default [ 
    takeLatest('requestUpdateElement', updateElementSaga), 
]; 

api.js

export function updateElement(element) { 
    const userId = JSON.parse(localStorage.cookies).userId; 
    element.userId = userId; 

    if (userId) { 
     return apiHelper.put(
      `${apiHelper.getBaseUrl()}/users/${element.userId}/elements/${element.id}`, 
      {element}, 
      {headers: apiHelper.getHeaders()} 
     ).catch((error) => { 
      return {error}; 
     }); 
    } else { 
     console.log('user ID could not be found for request'); 
    } 
} 

而且我elements/reducer.js

const defaultState = { 
    elementsMap: {}, 
    visibleElements: [], 
    unplacedElements: [], 
}; 

export default function(state = defaultState, action) { 
    switch (action.type) { 
     case 'receiveElement': 
      let element = null; 
      let unplacedElement = null; 

      if (action.element.sectorId === undefined) { 
       unplacedElement = `${action.element.id}`; 
      } else { 
       element = `${action.element.id}`; 

       // don't add, duplicate 
       const newState = {...state}; // copy old state 
       delete newState[`${action.element.id}`]; // delete the item from the object 
       const newVisibleElements = newState.visibleElements.filter(e => e !== `${action.element.id}`); // remove item from visible elements 
       const newUnplacedElements = newState.unplacedElements.filter(e => e !== `${action.element.id}`); 

       return { 
        ...newState, 
        elementsMap: { 
         ...newState.elementsMap, 
         [element]: action.element, 
        }, 
        visibleElements: [...newVisibleElements, element], 
        unplacedElements: [...newUnplacedElements], 
       }; 
      } 

      return { 
       ...state, 
       elementsMap: { 
        ...state.elementsMap, 
        [action.element.id]: action.element, 
       }, 
       visibleElements: [...state.visibleElements, element], 
       unplacedElements: [...state.unplacedElements, unplacedElement], 
      }; 
     default: 
      return state; 
    } 
} 

就像我之前提到的,有時更新工作,但不是每一次。我已經將問題縮小到了客戶端。服務器似乎行事不錯。任何想法我在這裏做錯了嗎?謝謝!

+0

你可以分享''receiveElement功能? – puemos

+0

從我的'/ elements/actions.js':'export function receiveElement(element)return {type:'receiveElement',element};' } –

回答

4

如果您正在使用takeLatest了Redux傳奇文檔中則提到:

https://redux-saga.js.org/docs/basics/UsingSagaHelpers.html

不像takeEvery,takeLatest只允許一個fetchData任務在 任何時刻運行。這將是最近開始的任務。如果之前的 任務仍在運行,當另一個fetchData任務啓動時,之前的任務將自動取消

哪裏fetchData是正在使用takeLatesttakeEvery

當你的UI保持調用同樣的動作,之前它被完成,它會保持取消 最後調用的動作提供發電機功能,因此你會繼續間歇性地收到消息:

updateElementSaga has been cancelled

根據其性質takeLatest是做正確的事。那就是:

Always take the latest invoked action

在要被捕獲並處理每一個動作,都使用takeEvery情況下,如:

export default [ 
    takeEvery('requestUpdateElement', updateElementSaga), 
]; 
+0

感謝Nagaraj。 –

+0

歡迎您:) –

相關問題