我很确定我没有正确使用 useReducer 有一个例子:
**//My array with some items**
const items = [
{
id: 0,
title: "Cidre Doux",
img:
"img",
type: "doux",
},
{
id: 1,
title: "Cidre demi-doux",
img:
"img",
type: "demi-doux",
},
]
**//UseState for passing category in dispatch**
const [categoryItem, setCategoryItem] = useState("");
**//useReducer**
const [state, dispatch] = useReducer(reducer, items);
function reducer(state, action) {
switch (action.type) {
case "all":
return [...items];
case categoryItem:
return items.map((item) =>
item.type === categoryItem ? { ...item } : null
);
default:
throw new Error();
}
}
**//function onClick**
const dispatchCategory = (category) => {
setCategoryItem(category);
dispatch({ type: category });
};
{...}
//Return
<button onClick={() => { dispatchCategory("doux");}}> Doux </button>
{...}
//My map
{state.map((item) => {
if (item != null) {
return <ShopCardItem key={item.id} {...item} />;
} else {
return "";
}
})}
在我的reducer 中,我使用items 而不是state,因为我有几个按钮可以找到一些类别对象。如果我使用状态我无法获得点击按钮后的所有项目。
如果我在函数 reducer 中使用 state 有一个例子:
步骤:一,点击“全部”=>所有项目,
步骤:二,点击“doux”=> doux items,
步骤:三,再次点击“全部”,只获得doux项目。
我该如何解决这个问题?
非常喜欢!
答案 0 :(得分:0)
你在这里做什么没有意义。您的 items
是一个常数。您选择的类别通过 useState
存储(未存储在 reducer 状态)。为什么需要减速器?
你的 reducer 违反了 reducer 的一些基本原则,比如依赖外部状态。好消息是你的组件很容易修复,因为 reducer 几乎可以完全删除。我们要保留的逻辑是如何从类别状态派生当前项目。此筛选项列表是从状态派生的变量。它不需要存储在状态本身。
我们看categoryItem
。如果为空,则currentItems
是所有项目,如果是类别,则currentItems
是与类别匹配的项目。我将使用 ""
来表示 all 而不是 "all"
,因为您的 useState
的初始值是 ""
。无论您使用什么,保持一致。
const currentItems = categoryItem === "" ? items : items.filter( item => item.type === categoryItem );
就是这样。所以现在删除整个useReducer
。当您映射项目时,现在是 state.map
而不是 currentItems.map
。您也可以删除 dispatchCategory
函数。使用 dispatchCategory("doux")
代替 setCategoryItem("doux")
。