2017-07-19 140 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

欢迎您:) –

相关问题