#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:
Я думаю, у тебя есть пара проблем.
- Вы в основном храните дубликаты данных, когда сохраняете оригинальную копию пользовательских данных и отфильтрованную копию. Отфильтрованные пользователи — это просто производные данные, основанные на состоянии пользователя и текущем значении фильтра. Вы должны сохранить значение фильтрации в состоянии и выполнить встроенную фильтрацию при рендеринге.
- Когда выбираются новые пользователи, они не добавляются в существующее состояние.
Предложения по коду:
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} />;
})
}