Reactjs, фильтр поиска работает неправильно, когда я загружаю больше пользователей

#reactjs

Вопрос:

Я извлекаю данные пользователей из dummyapi и перечисляю их на странице. В начале в списке 15 пользователей, и если вы нажмете «загрузить больше», в списке будет еще 15. У меня есть поисковый ввод, он фильтрует пользователей по именам. Я могу правильно отфильтровать первых 15 пользователей. Когда я нажимаю «Загрузить больше» и добавляю еще 15 пользователей, он по-прежнему фильтрует только первых 15 пользователей. Как я могу это исправить, вы можете помочь ?

 import { useEffect, useState } from "react";
import Header from "../components/Header";
import User from "./User";
import axios from "axios";

function App() {
  const BASE_URL = "https://dummyapi.io/data/api";
  const APP_ID = "your app id";

  const [users, setUsers] = useState(null);
  const [allUsers, setAllUsers] = useState(null);
  const [limit, setLimit] = useState(15);

  const handleChange = (e) => {
    const keyword = e.target.value.toLowerCase();
    const filteredUsers =
      allUsers amp;amp;
      allUsers.filter((user) => user.firstName.toLowerCase().includes(keyword));
    setUsers(filteredUsers);
  };

  const handleClick = () => {
    setLimit(limit * 2);
  };

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await axios.get(`${BASE_URL}/user?limit=${limit}`, {
          headers: { "app-id": APP_ID },
        });
        setUsers(response.data.data);
        setAllUsers(response.data.data);
      } catch (error) {
        console.log(error);
      }
    }
    fetchData();
  }, [limit]);

  return (
    <>
      <Header />
      <div className="container">
        <div className="filter">
          <h3 className="filter__title">USER LIST</h3>
          <div>
            <input
              id="filter"
              className="filter__input"
              type="text"
              placeholder="Search by name"
              onChange={handleChange}
            />
          </div>
        </div>

        <div className="user__grid">
          {users amp;amp;
            users.map((user, index) => {
              const { id } = user;
              return <User key={index} id={id} />;
            })}
        </div>
        <div className="loadMore" onClick={handleClick}>
          <span>Load More</span>
        </div>
      </div>
    </>
  );
}

export default App;

 

Ответ №1:

Каждый раз, когда вы получаете пользователей с сервера, вы должны объединять их с текущими пользователями в вашем штате, см. Код:

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await axios.get(`${BASE_URL}/user?limit=${limit}`, {
          headers: { "app-id": APP_ID },
        });

        setAllUsers(prevState => {
          return [...prevState, response.data.data]
        });
      } catch (error) {
        console.log(error);
      }
    }
    fetchData();
  }, [limit]);
 

Ответ №2:

Я думаю, у тебя есть пара проблем.

  1. Вы в основном храните дубликаты данных, когда сохраняете оригинальную копию пользовательских данных и отфильтрованную копию. Отфильтрованные пользователи — это просто производные данные, основанные на состоянии пользователя и текущем значении фильтра. Вы должны сохранить значение фильтрации в состоянии и выполнить встроенную фильтрацию при рендеринге.
  2. Когда выбираются новые пользователи, они не добавляются в существующее состояние.

Предложения по коду:

 const [users, setUsers] = useState(null);
const [search, setSearch] = useState('');

const handleChange = (e) => {
  setSearch(e.target.value.toLowerCase());
};


useEffect(() => {
  async function fetchData() {
    try {
      const response = await axios.get(`${BASE_URL}/user?limit=${limit}`, {
        headers: { "app-id": APP_ID },
      });
      setUsers(users => users.concat(response.data.data));
    } catch (error) {
      console.log(error);
    }
  }
  fetchData();
}, [limit]);

...

{users.filter((user) => user.firstName.toLowerCase().includes(keyword))
  .map((user, index) => {
    const { id } = user;
    return <User key={index} id={id} />;
  })
}