尽管使用回调函数更新状态,但filteredBooks
状态仅在第二次点击后更新。
import { useRef, useEffect, useState } from "react";
import "./App.css";
import Card from "./UI/Card";
function App() {
const [books, setBooks] = useState([]);
const [filteredBooks, setFilteredBooks] = useState([]);
const [yearRange, setYearRange] = useState([]);
const filterBksByYearRange = () => {
const filtered = books.filter(
(book) => book.year >= yearRange[0] && book.year <= yearRange[1]
);
setFilteredBooks(() => filtered);
};
const handleYrRange = (e) => {
e.preventDefault();
const yearStart = parseInt(e.target[0].value);
const yearEnd = parseInt(e.target[1].value);
console.log(yearStart, yearEnd);
setYearRange(() => [yearStart, yearEnd]);
// SOLVE: books complete list only at initial fetch. if multiple filters applied, will not reflect accurate filter
filterBksByYearRange();
};
useEffect(() => {
const url = "/books";
const fetchData = async () => {
try {
const response = await fetch(url);
const json = await response.json();
console.log(json);
setBooks((prev) =>
[prev, ...json.body].map((book) => {
return {
title: book.title,
author: book.author,
year: parseInt(book.year),
isbn: parseInt(book.isbn),
};
})
);
} catch (error) {
console.log("error", error);
}
};
fetchData();
}, []);
return (
<div className="App">
<h1>ServicePros Coding Challenge</h1>
<form onSubmit={handleYrRange}>
<label>
Start Year:
<input type="text" name="yearStart" placeholder="" />
</label>
<label>
Start End:
<input type="text" name="yearEnd" placeholder="" />
</label>
<button type="submit">Filter by Year</button>
</form>
<ul>
{filteredBooks.length > 0 ? (
filteredBooks.map((book) => (
<Card key={Math.random()}>
<li>
<div>Title: {book.title}</div>
<div>Author: {book.author}</div>
<div>Year: {book.year}</div>
<div>ISBN: {book.isbn}</div>
</li>
</Card>
))
) : (
<p>No Books Filtered</p>
)}
</ul>
</div>
);
}
export default App;
2条答案
按热度按时间oogrdqng1#
因为
filterBksByYearRange();
基于yearRange
状态工作,并且后者不会在更新时立即更改,而是在下一次渲染时更改,因此:一种替代方法是更新您的
filterBksByYearRange()
函数:并这样使用它:
g52tjvyc2#
第一次单击时
filteredBooks
状态没有更新的原因是setYearRange
和filterBkByYearRange
函数是异步的,这意味着filteredBooks
状态是用yearRange
的先前值而不是更新后的值设置的。要解决这个问题,你可以把
filterBkByYearRange
函数移到一个依赖yearRange的useEffect
钩子中,如下所示: