使用redux-toolkit过滤通知

k4emjkb1  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(145)

这是我的notesSlice:

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const url = "http://localhost:8000/";

const initialState = {
  notices: [],
};

export const getNotices = createAsyncThunk(
  "notices/getNotices",
  async (_name, thunkAPI) => {
    try {
      const resp = await axios(`${url}notices`);
      return resp.data;
    } catch (error) {
      return thunkAPI.rejectWithValue("something went wrong");
    }
  }
);

const noticesSlice = createSlice({
  name: "notices",
  initialState,
  reducers: {
    filterNotices: (state, { payload }) => {
      console.log(state.notices)
      console.log(payload)

      if (payload.searchOption === "Simple") {
        state.notices = state.notices.filter((note) =>
          note.title.toLowerCase().includes(payload.search.toLowerCase())
        );
      } else if (payload.searchOption === "Advanced") {
        state.notices = state.notices.filter(
          (note) =>
            note.description
              .toLowerCase()
              .includes(payload.search.toLowerCase()) ||
            note.tags.filter((tag) => {
              tag.toLowerCase().includes(payload.search.toLowerCase());
            })
        );
      }
    },

  },
  extraReducers: (builder) => {
    builder
      .addCase(getNotices.fulfilled, (state, { payload }) => {
        state.notices = payload;
      })

filterNotice方法的payload中,我正在发送带有search输入和searchOption的对象。我应该如何在每次调用filterNotice方法时搜索所有通知?这是正确的方法吗?

yc0p9oo0

yc0p9oo01#

不要通过过滤来改变你的真理来源。过滤后的结果应该是从notices状态和search值计算/导出的“状态”。

如果不需要持久化过滤后的通知

将搜索类型和值存储在state中,并使用选择器函数计算派生的state。

const initialState = {
  notices: [],
  searchOption: "Simple",
  searchValue: "",
};
    
const noticesSlice = createSlice({
  name: "notices",
  initialState,
  reducers: {
    setSearch: (state, action) => {
      const { searchOption, search } = action.payload;
      state.searchOption = searchOption;
      state.searchValue = search.toLowerCase();
    },
    ...
  },
  ...
});

export const selectFilteredNotices = state => {
  const { notices, searchOption, searchValue } = state.path.to.notices;

  switch(searchOption) {
    case "Simple":
      return notices.filter((note) =>
        note.title.toLowerCase().includes(searchValue)
      );

    case "Advanced":
      return notices.filter((note) =>
        note.description.toLowerCase().includes(searchValue) ||
        note.tags.some((tag) => tag.toLowerCase().includes(searchValue))
      );

    default:
      return notices;
  }
};

UI将分派setSearch操作来更新搜索值,并使用useSelector钩子和selectFilteredNotices函数来选择过滤后的通知值。

const dispatch = useDispatch();
const filteredNotices = useSelector(selectFilteredNotices);

...

dispatch(setSearch({ searchOption, search }));
...

如果您确实需要将过滤后的通知持久化到状态

在state中创建一个新的filteredNotices数组,在分派filterNotices操作时,您将过滤未更改的state.notices数组并返回/更新state.filteredNotices数组。这会使原始通知数据保持不变。

const initialState = {
  notices: [],
  filteredNotices: [],
};
    
const noticesSlice = createSlice({
  name: "notices",
  initialState,
  reducers: {
    filterNotices: (state, action) => {
      const { searchOption, search } = action.payload;
      const searchValue = search.toLowerCase();

      if (searchOption === "Simple") {
        state.filteredNotices = state.notices.filter((note) =>
          note.title.toLowerCase().includes(searchValue)
        );
      } else if (searchOption === "Advanced") {
        state.filteredNotices = state.notices.filter((note) =>
          note.description.toLowerCase().includes(searchValue) ||
          note.tags.some((tag) => tag.toLowerCase().includes(searchValue))
        );
      }
    },
    ...
  },
  ...
});

相关问题