我试图通过React中的button onClicks过滤我的结果,但由于某种原因它不起作用?
https://stackblitz.com/edit/react-x7tlxr?file=src/App.js
import React, {useEffect, useState} from "react";
import axios from 'axios';
import "./style.css";
export default function App() {
const [fetchData, setFetchData] = useState([]);
const [loading, setLoading] = useState(true);
const [isError, setIsError] = useState(false);
const url = 'https://jsonplaceholder.typicode.com/todos';
useEffect(() => {
let mounted = true;
const loadData = async () => {
try {
const response = await axios(url);
if (mounted) {
setFetchData(response.data);
setLoading(false);
setIsError(false);
console.log('data mounted')
}
} catch (err) {
setIsError(true)
setLoading(false);
setFetchData([]);
console.log(err);
}
};
loadData();
return () => {
mounted = false;
console.log('cleaned');
};
},
[url]
);
const renderdata = () => {
if (fetchData) {
return (
<div>{fetchData.map(inner => {
return (
<React.Fragment key={inner.id}>
<p>{inner.title}</p>
</React.Fragment>
)
})}</div>
)
} else {
<p>No data to display!</p>
}
}
const handle1 = () => {
const result1 = fetchData.filter((inner) => inner.id === '1');
setFetchData(result1);
}
const handle2 = () => {
const result2 = fetchData.filter((inner) => inner.id === '2');
setFetchData(result2);
}
const handleAll = () => {
setFetchData(fetchData);
}
return (
<div>
<button onClick={handleAll}>Show all</button>
<button onClick={handle1}>Filter by id 1</button>
<button onClick={handle2}>Filter by id 2</button>
{renderdata()}
</div>
);
}
id
是一个数字,而不是字符串,所以您需要这样更改过滤器:
const result1 = fetchData.filter((inner) => inner.id === 1);
你还有另一个问题,当你过滤的时候你改变了整个数据集,所以一旦你过滤了,你就不能"unfilter"了。或者在另一个id上再次过滤。
保持原fetchedData
不变
这个例子展示了如何修复它。
我在你的代码中发现了两个问题
-
API结果中的Id是数字而不是字符串
inner.id === '2'
。所以这将返回falseinner.id === 2
,你需要像这样使用 -
当你将过滤值分配给原始数组时,它当然会改变原始数组,所以当你第二次尝试过滤它时,你在fetch data数组中没有原始API结果,因为它已经被过滤了所以我又创建了一个数组
filteredData
import React, {useEffect, useState} from "react"; import axios from 'axios'; import "./style.css"; export default function App() { const [fetchData, setFetchData] = useState([]); const [filteredData, setFileredData] = useState([]); const [loading, setLoading] = useState(true); const [isError, setIsError] = useState(false); const url = 'https://jsonplaceholder.typicode.com/todos'; useEffect(() => { let mounted = true; const loadData = async () => { try { const response = await axios(url); if (mounted) { setFetchData(response.data); setFileredData(response.data) setLoading(false); setIsError(false); console.log('data mounted') } } catch (err) { setIsError(true) setLoading(false); setFetchData([]); console.log(err); } }; loadData(); return () => { mounted = false; console.log('cleaned'); }; }, [url] ); const renderdata = () => { if (filteredData) { return ( <div>{filteredData.map(inner => { return ( <React.Fragment key={inner.id}> <p>{inner.title}</p> </React.Fragment> ) })}</div> ) } else { <p>No data to display!</p> } } const handle1 = () => { const result1 = fetchData.filter((inner) => inner.id === 1); setFileredData(result1); } const handle2 = () => { const result2 = fetchData.filter((inner) => inner.id === 2); setFileredData(result2); } const handleAll = () => { setFileredData(fetchData); } return ( <div> <button onClick={handleAll}>Show all</button> <button onClick={handle1}>Filter by id 1</button> <button onClick={handle2}>Filter by id 2</button> {renderdata()} </div> ); }