SearchReducer,搜索到的项目从reduxstore中删除

问题描述 投票:0回答:1
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

在这里,当我搜索返回搜索结果时,但在搜索与搜索查询不匹配的所有其他产品后,会从商店中删除。

我需要在搜索时显示搜索结果,如果不搜索则显示所有产品。

javascript search redux react-hooks redux-toolkit
1个回答
0
投票

在这里,当我搜索返回搜索结果,但搜索完所有其他 与搜索查询不匹配的产品将从中删除 商店。

这就是

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));
© www.soinside.com 2019 - 2024. All rights reserved.