gpt4 book ai didi

javascript - 在中间件中调度 redux 操作会导致意外行为

转载 作者:行者123 更新时间:2023-11-30 19:58:20 25 4
gpt4 key购买 nike

我试图了解 redux 中间件的工作原理,在我的实验过程中,我注意到从 redux 中间件分派(dispatch)操作可能会导致意外行为。

我将尝试通过模拟文件上传来解释问题,如下所示:

我们有 3 个 Action :

const setProgress = (progress) => ({ type: SET_UPLOAD_PROGRESS, progress });
const setThumbnail = (thumbnail) => ({ type: SET_THUMBNAIL, thumbnail });
const calculateTotal = () => ({ type: CALCULATE_TOTAL });

计算总数的中间件:

export const testMiddleware = (store) => (next) => (action) => {
if (action.type === 'CALCULATE_TOTAL') {
return next(action);
}
const result = next(action);
store.dispatch(calculateTotal());
return result;
};

reducer :

const initialState = {
progress: 0,
total: 0,
thumbnail: ''
};
export function uploadReducer(state = initialState, action) {
switch (action.type) {
case SET_UPLOAD_PROGRESS:
state.progress = action.progress;
return { ...state };
case SET_THUMBNAIL:
state.thumbnail = action.thumbnail;
return { ...state };
case CALCULATE_TOTAL:
state.total += state.progress * 5;
return { ...state };
default:
return state;
}
}

这里是模拟文件上传的代码:

  let cnt = 0;
// simulate upload progress
const setNewProgress = () => {
cnt += 2;
if (cnt > 5) return;
setTimeout(() => {
store.dispatch(setProgress(cnt * 2));
setNewProgress();
}, 1000);
};
setNewProgress();
// simulate thumbnail generating
setTimeout(() => {
store.dispatch(setThumbnail('blob:http://thumbnail.jpg'));
}, 2500);

这是事件的顺序:

第一个 Action 按预期工作并设置进度值:

enter image description here

问题从这里开始;缩略图应该由“setThumbnail”设置,但 devtools 显示它已由“calculateTotal”设置,并且之后的每个调度都不匹配:

enter image description here

我在这里做错了什么?是设计使然吗?如何在不引起上述问题的情况下在中间件中发送操作?

最佳答案

这种意外行为可能是由于您的 uploadReducer 不是 pure 引起的,即它直接对您的状态进行操作(例如 state.progress = action.progress;)。 reducer should只返回新状态而不修改通过 redux 注入(inject)到你的 reducer 中的现有状态。因此,您的 reducer 需要如下所示:

export function uploadReducer(state = initialState, action) {
switch (action.type) {
case SET_UPLOAD_PROGRESS:
return { ...state, progress: action.progress };
case SET_THUMBNAIL:
return { ...state, thumbnail: action.thumbnail };
case CALCULATE_TOTAL:
return { ...state, total: state.total + state.progress * 5 };
default:
return state;
}
}

how can I dispatch an action in middleware without causing above problem?

您的中间件看起来不错(您正确地防止了递归并返回了 next() 结果(您的示例中不需要它,但在实际应用程序中仍然有意义)。您的操作看起来不错以及(风格评论:您可以将操作的有效负载包装在 payload 属性中,这是一个常见的 convention )。

关于javascript - 在中间件中调度 redux 操作会导致意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53686346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com