@gaming_shark

Почему не обновляется состояние?

import "./styles.css";
import React from "react";

export default function App() {
  const [items, setItems] = React.useState([
    { name: "Valerka", id: 1 },
    { name: "Vasya", id: 2 },
  ]);

  const [search, setSearch] = React.useState("");
  const [name, setName] = React.useState("");
  const createNewItem = () => {
    const user = {
      name,
      id: Date.now(),
    };
    setItems([...items, user]);
    setName("");
  };
  const deleteItem = (id) => {
    setItems(items.filter((item) => item.id !== id));
  };
  const searchItems = (searchText, users) => {
    if (!searchText) {
      return users;
    }
    return (filteredItems = users.filter(({ name }) =>
      name.toLowerCase().includes(searchText.toLowerCase())
    ));
  };
  React.useEffect(() => {
    const debouncedSearch = setTimeout(() => {
      const filteredItems = searchItems(search, items);
      setItems(filteredItems);
    }, 500);
    return () => {
      clearTimeout(debouncedSearch);
    };
  }, [search]);
  return (
    <div className="App">
      <input
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        type="text"
        placeholder="Find item by name"
      ></input>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        type="text"
        placeholder="Enter your name"
      ></input>

      <button onClick={createNewItem}>Submit</button>
      {items.map((item) => (
        <div key={`${item.id} + ${item.name}`} className="block">
          <div className="information">
            <div>{item.name}</div>
            <div>{item.id}</div>
          </div>
          <button onClick={() => deleteItem(item.id)}>Delete</button>
        </div>
      ))}
    </div>
  );
}


Поиск работает, НО когда стираю значение в инпуте, то что было ранее в items до поиска не отображается. Как это исправить?
  • Вопрос задан
  • 121 просмотр
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега React
Не нужно сохранять результат items.filter() в state, туда нужно класть только поисковую фразу, а фильтровать просто при рендере налету перед .map().
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
kryamk
@kryamk
export default function App() {
  const [originalItems, setOriginalItems] = React.useState([
    { name: "Valerka", id: 1 },
    { name: "Vasya", id: 2 },
  ]);
  const [items, setItems] = React.useState(originalItems);

  const [search, setSearch] = React.useState("");
  const [name, setName] = React.useState("");

  const createNewItem = () => {
    const user = {
      name,
      id: Date.now(),
    };
    setOriginalItems([...originalItems, user]);
    setItems([...originalItems, user]);
    setName("");
  };

  const deleteItem = (id) => {
    setOriginalItems(originalItems.filter((item) => item.id !== id));
    setItems(items.filter((item) => item.id !== id));
  };

  const searchItems = (searchText, users) => {
    if (!searchText) {
      return users;
    }
    return users.filter(({ name }) =>
      name.toLowerCase().includes(searchText.toLowerCase())
    );
  };

  React.useEffect(() => {
    const debouncedSearch = setTimeout(() => {
      const filteredItems = searchItems(search, originalItems);
      setItems(filteredItems);
    }, 500);
    return () => {
      clearTimeout(debouncedSearch);
    };
  }, [search, originalItems]);

  return (
    <div className="App">
      <input
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        type="text"
        placeholder="Find item by name"
      ></input>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        type="text"
        placeholder="Enter your name"
      ></input>

      <button onClick={createNewItem}>Submit</button>
      {items.map((item) => (
        <div key={`${item.id} + ${item.name}`} className="block">
          <div className="information">
            <div>{item.name}</div>
            <div>{item.id}</div>
          </div>
          <button onClick={() => deleteItem(item.id)}>Delete</button>
        </div>
      ))}
    </div>
  );
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы