我正在使用 useEffect 從 API 檢索一些資料,并且我希望能夠使用從其父級饋入組件的 prop 過濾回傳的資料。
我試圖在 useEffect 設定狀態后對其進行過濾,但是看起來該組件正在進入無限渲染回圈。
我需要做什么來防止這種情況發生?
export default function HomeJobList(props: Props): ReactElement {
const [listings, setListings] = React.useState(null);
useEffect(() => {
const func = async () => {
let res = await service.getListings();
setListings(res);
};
func();
}, []);
if (props.searchTerm && listings) {
let filtered = listings.filter((x) => x.positionTitle.includes(props.searchTerm));
setListings(filtered);
}
return (
<>
<div>do stuff</div>
</>
);
}
我知道使用 setListing 函式會導致過濾后重新渲染,然后導致另一個 setListing 呼叫。但是打破這個回圈的最好方法是什么?
我是否應該只有另一個狀態值來維護用于過濾的最后一個 searchTerm 并在過濾之前進行檢查?
或者,還有更好的方法?
uj5u.com熱心網友回復:
這是一個無限回圈,因為每次過濾時,您都將其設定為狀態變數,這會導致重新渲染和過濾并再次設定變數 - 因此是一個回圈。
我建議你在一個地方做這一切(你useEffect是一個很好的地方,因為它只執行一次。
useEffect(() => {
(async () => {
const res = await service.getListings();
const filtered = res.filter((x) => x.positionTitle.includes(props.searchTerm));
setListings(filtered);
})();
}, []);
uj5u.com熱心網友回復:
當狀態改變觸發重新渲染時,這就是為什么你有一個無限回圈;您需要做的是將您的過濾包裝在一個取決于searchTerm道具的 useEffect 中,如下所示:
import React, { useEffect } from 'react';
export default function HomeJobList() {
const [listings, setListings] = React.useState(null);
useEffect(() => {
const func = async () => {
let res = await service.getListings();
setListings(res);
};
func();
}, []);
useEffect(() => {
if (listings) {
let filtered = listings.filter(x =>
x.positionTitle.includes(props.searchTerm)
);
setListings(filtered);
}
}, [props.searchTerm]);
return (
<>
<div>do stuff</div>
</>
);
}
uj5u.com熱心網友回復:
您需要創建一個在您回傳的 JSX 中呼叫的函式。
實際上,每次Props物件更改時都需要渲染組件。這是通過呼叫 JSX 代碼中的函式來實作的。
例子:
功能:
const filteredListings = () => {
if (props.searchTerm && listings) {
let filtered = listings.filter((x) => {
x.positionTitle.includes(props.searchTerm));
}
return filtered;
}
}
退貨宣告:
return (
<ul>
{
filteredListings().map((listing) =>
<li>{listing.title}</li>
);
}
</ul>
);
uj5u.com熱心網友回復:
您需要的是useEffect在道具更改時進行過濾。
替換這個
if (props.searchTerm && listings) {
let filtered = listings.filter((x) => x.positionTitle.includes(props.searchTerm));
setListings(filtered);
}
和
useEffect(()=>{
if (props.searchTerm) {
setListings(prevListing => {
return prevListing.filter((x) => x.positionTitle.includes(props.searchTerm))
});
}
}, [props.searchTerm] )
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/399857.html
標籤:反应
