import { createSlice } from "@reduxjs/toolkit";
export const productSlice = createSlice({
name: 'products',
initialState: [],
reducers: {
addProduct: (state, action) => {
state.push(action.payload)
console.log(state)
},
deleteProduct: (state, action) => {
// const {title} = action.payload;
return state.filter(item => item.title !== action.payload)
},
searchProduct: (state, action) => {
if (!action.payload.trim()) {
return state
} else {
const res = state.filter(
item => item.title.toLowerCase().includes(
action.payload.toLowerCase()
)
);
return res
}
}
}
})
export const {
addProduct,
deleteProduct,
searchProduct
} = productSlice.actions
export default productSlice.reducer
在这里,当我搜索返回搜索结果时,但在搜索与搜索查询不匹配的所有其他产品后,会从商店中删除。
我需要在搜索时显示搜索结果,如果不搜索则显示所有产品。
在这里,当我搜索返回搜索结果,但搜索完所有其他 与搜索查询不匹配的产品将从中删除 商店。
这就是
Array.filter
的作用,它从源数组中过滤出值并返回新数组,这是一个 reducing 操作,即删除信息。一旦过滤掉它,就无法再过滤回来。
如果您只是想要一个过滤视图,那么您可能不想改变源状态。
您应该只过滤本地选择的产品数组副本,而不是调度
searchProduct
操作来直接过滤状态。
示例:
const [search, setSearch] = React.useState("");
const products = useSelector(state => state.products);
const updateSearch = (value = "") => setSearch(value.toLowerCase());
const filteredProducts = React.useMemo(() => {
return products.filter(
item => item.title.toLowerCase().includes(search)
);
}, [products, search]);
如果您更喜欢在 Redux 存储中计算并保留“过滤视图”,则将搜索项添加到 Redux 状态并在选择器函数中计算过滤视图。
示例:
export const productSlice = createSlice({
name: 'products',
initialState: [],
reducers: {
addProduct: (state, action) => {
state.push(action.payload);
},
deleteProduct: (state, action) => {
return state.filter(item => item.title !== action.payload)
},
})
export const { addProduct, deleteProduct } = productSlice.actions;
export default productSlice.reducer;
export const productSearchSlice = createSlice({
name: "productSearch",
initialState: "",
reducers: {
searchProduct: {
reducer: (state, action) => action.payload,
prepare: (search = "") = ({
payload: search.toLowerCase(),
}),
},
},
});
export const { searchProduct } = productSearchSlice.actions;
export default productSearchSlice.reducer;
import { createSelector } from '@reduxjs/toolkit';
export const selectProducts = state => state.products;
export const selectProductSearch = state => state.productSearch;
export const selectFilteredProducts = createSelector(
[selectProducts, selectProductSearch],
(products, search) => products.filter(
item => item.title.toLowerCase().includes(search)
),
);
const dispatch = useDispatch();
const filteredProducts = useSelector(selectFilteredProducts);
const updateSearch = (value = "") => dispatch(searchProduct(value));