Reducer以意想不到的方式被调用- Redux Saga



嘿,我有一个小问题,试图做一个小的待办事项应用程序。错误显示在浏览器的控制台中,UI没有中断,但它让我发疯,因为我想知道为什么会发生这种情况?

我用它的参数调用setChecked的主组件,要检查的项目的id和checkedValue(true或false)。

import { useSelector, useDispatch } from "react-redux";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import { setChecked } from "../redux/actions/todoActions";
export default function Main() {
const tasks = useSelector((state) => state.todoReducer.tasks);
const dispatch = useDispatch();
const taskItems = Array.from(tasks).map((item, index) => {
return item.checked !== true && item.date ? (
<div
key={index}
className="item-row"
onClick={() => dispatch(setChecked(item.id, !item.checked))}
>
<label className="check-flag">
<span className="check-flag-label">{item.title}</span>
<FormControlLabel
className="checkbox"
control={
<Checkbox className="checkbox-native" checked={item.checked} />
}
></FormControlLabel>
</label>
</div>
) : (
""
);
});
return (
<main className="main">
<div className="wrap">{taskItems}</div>
</main>
);
}

setChecked行动

const setChecked = (id, checked) => ({
type: TODO.SET_CHECKED,
itemToChange: { id, checked },
});

todoSaga

function* handleGetTodo(action) {
yield put({ type: TODO.GET_TODO });
}
function* handleSetChecked(action) {
yield put({ type: TODO.SET_CHECKED, action });
}
export default function* watchTodo(action) {
yield takeEvery(TODO.GET_TODO, handleGetTodo);
yield takeLatest(TODO.SET_CHECKED, handleSetChecked);
}

齿轮

const todoReducer = (state = initialState, action) => {
switch (action.type) {
case TODO.GET_TODO:
return { ...state };
case TODO.SET_CHECKED:
var tasks = state.tasks;
tasks = tasks.map((item) => {
if (item.id === action.itemToChange.id) {
return { ...item, checked: action.itemToChange.checked };
}
return { ...item };
});
return { ...state, tasks: tasks };
default:
return { ...state };
}
};

第一次调用- this is ok

第二个调用-整个动作被传递给动作,所以现在我有action.action. itemtochange

我正在使用React。StrictMode,我理解它必须调用一些函数两次这不是问题,但为什么他使嵌套的动作对象内部的动作对象本身?我希望我成功地表达了自己。

感谢您的宝贵时间

现在你的英雄没有任何意义,因为你正在执行一个操作,然后分发本质上相同的操作。实际上,这样做可能会创建一个无限循环。

您在redux-saga创建的操作版本中获得嵌套操作的原因是由于您如何在handleSetChecked函数中创建操作。它接收一个参数action,它是被take截获的整个动作对象。然后使用put调度一个看起来像yield put({ type: TODO.SET_CHECKED, action });的新动作,该动作具有typeaction的属性,其中action是整个原始动作。

最新更新