【发布时间】:2021-05-09 02:39:31
【问题描述】:
嘿,我遇到了一个小问题,正在尝试制作小型 todo 应用程序。错误显示在浏览器的控制台中,UI 没有中断,但它让我抓狂,因为我想知道为什么会这样?
我用它的参数调用 setChecked 的主要组件,要检查的项目的 id 和 checkValue(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 };
}
};
Second call - whole action gets passed to action so now i have action.action.itemToChange
我正在使用 React.StrictMode 并且我知道它必须调用某些函数两次,这不是问题,但为什么他在动作对象本身内部制作嵌套动作对象?我希望我能成功地表达自己。
感谢您的宝贵时间
【问题讨论】:
-
Re:奇怪的属性名称,这就是 redux-saga 在幕后的工作方式。它是一个中间件,因此它知道如何处理看起来像这样的动作。向下滚动到 API 文档中的“actionDispatched(action)”部分redux-saga.js.org/docs/api
-
action : Object - 调度的 Redux 操作。如果 action 是由 Saga 调度的,那么该 action 的属性 SAGA_ACTION 将设置为 true(SAGA_ACTION 可以从 @redux-saga/symbols 导入)。
-
Re: 嵌套动作,这是因为你在 handleSetChecked 中创建的动作。 yield put({ type: TODO.SET_CHECKED, action }) — 您将整个操作传递给属性操作。
标签: reactjs redux redux-saga reducers