Zac*_*iro 3 javascript reactjs redux react-redux
我刚刚使用react-dnd实现了一个拖放功能,当用户SkyElement在我的应用程序中删除项目时,我更新top并left在服务器上反过来更新redux存储
但是,更新调用偶尔会有效,而不是每次都有效.在我的控制台中,我看到了警告;updateElementSaga has been cancelled
在我SlotView.js的功能中,我有:
this.props.dispatch(requestUpdateElement({ id, top, left }));
在我的elements/actions.js:
export function requestUpdateElement(element) {
return { type: 'requestUpdateElement', element };
}
Run Code Online (Sandbox Code Playgroud)
在我的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),
];
Run Code Online (Sandbox Code Playgroud)
在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');
}
}
Run Code Online (Sandbox Code Playgroud)
我的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;
}
}
Run Code Online (Sandbox Code Playgroud)
就像我之前提到的,有时更新有效,但不是每次都有效.我把问题缩小到了客户端.服务器似乎行事正常.知道我在这里做错了吗?谢谢!
如果您使用的takeLatest是redux saga文档确实提到:
https://redux-saga.js.org/docs/basics/UsingSagaHelpers.html
与takeEvery不同,takeLatest只允许一个fetchData任务随时运行.这将是最新开始的任务.如果在启动另一个fetchData任务时前一个任务仍在运行, 则前一个任务将自动取消.
fetchData使用takeLatest或提供的生成器函数在哪里?takeEvery
当你的UI继续调用相同的动作时,在它完成之前,它将继续取消最后一次调用的动作,因此你会间歇性地获取消息:
updateElementSaga has been cancelled
这本质上takeLatest是正确的做法.这是:
Always take the latest invoked action
如果您希望捕获并处理每个操作,请使用takeEvery,如下所示:
export default [
takeEvery('requestUpdateElement', updateElementSaga),
];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |