简体   繁体   English

防止在 React 中过滤时更改本地存储

[英]Prevent local storage from being changed when filtering in React

Whenever I dispatch a search action using context and useReducer for an object in an array stored in local storage, it returns the object, but when I delete the search query from the input box, the list is not returned and the page is blank, can anyone help please?每当我使用 context 和useReducer为存储在本地存储中的数组中的 object 调度搜索操作时,它会返回 object,但是当我从输入框中删除搜索查询时,不会返回列表并且页面是空白的,可以有人帮忙吗?

This is my context:这是我的背景:

const NotesContext = createContext(null);
const NotesDispatchContext = createContext(null);

const getStoredNotes = (initialNotes = InitialNotes) => {
  return JSON.parse(localStorage.getItem("storedNotes")) || initialNotes;
};

export const NotesProvider = ({ children }) => {
  const [NOTES, dispatch] = useReducer(NotesReducer, getStoredNotes());
  useEffect(() => {
    localStorage.setItem("storedNotes", JSON.stringify(NOTES));
  }, [NOTES]);

  return (
    <NotesContext.Provider value={NOTES}>
      <NotesDispatchContext.Provider value={dispatch}>
        {children}
      </NotesDispatchContext.Provider>
    </NotesContext.Provider>
  );
};

export const useNotesContext = () => {
  return useContext(NotesContext);
};
export const useNotesDispatchContext = () => {
  return useContext(NotesDispatchContext);
};

const App = () => {
  const [query, setQuery] = useState("");
  const dispatch = useNotesDispatchContext();

  useEffect(() => {
    if (query.length !== 0) {
      dispatch({
        type: "searchNotes",
        query: query,
      });
    }
  }, [query]);
  return (
    <div className="container">
      <header>
        <Title title={"Notes"} className={"app_title"} />
        <form className="search_container">
          <span class="material-symbols-outlined">search</span>
          <input
            type="search"
            placeholder="search notes"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
        </form>
      </header>

This is my reducer function这是我的减速机 function

case "searchNotes": {
      [...NOTES].filter((note) =>
        note.title.toLowerCase().includes(action.query)
      );
    }

The function seems to actually remove the all data from the local storage instead of filtering based on the query string. function 似乎实际上是从本地存储中删除所有数据,而不是根据查询字符串进行过滤。

Issue问题

When you dispatch searchNotes , you are changing NOTES and the blow useEffect runs.当您发送searchNotes时,您正在更改NOTES并且打击useEffect运行。 So if the filter results to an empty NOTES , there would be nothing in localStorage .因此,如果过滤器结果为空NOTES ,则localStorage中将没有任何内容。

useEffect(() => {
  localStorage.setItem("storedNotes", JSON.stringify(NOTES));
}, [NOTES]);

Solution解决方案

What you can do is to remove that useEffect in App that has query as dependency and dispatching searchNotes .您可以做的是删除App useEffect query作为依赖项并调度 searchNotes 的searchNotes And filter directly while rendering, something like this:并在渲染时直接过滤,如下所示:

{
  NOTES.filter((note) => note.title.toLowerCase().includes(query)).map((note, index) => (
    <div key={index}>{note.title}</div>
  ));
}

And at this point you can searchNotes case from your reducer.此时您可以从减速器中searchNotes案例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM