[英]React - Updating previous array with new values using useState hook
我創建了一個包含三個組件HomeHeader
、 CompanyList
和ScrollToTopBtn
的主頁。 專注於CompanyList
,它是一個容器組件,顯示在Home
中使用 API 獲取的CompanyCards
列表。 公司列表在Home
中像這樣初始化
const [companies, setCompanies] = useState([]);
問題是最初在撥打 API 之后,我使用 spread operator 像這樣更新companies
列表
const fetchedCompanies = await fetchFeedData(page);
console.log(fetchedCompanies);
setCompanies((prevCompanies=>{return [...prevCompanies,fetchedCompanies]}));
console.log(companies);
但是發生錯誤Uncaught TypeError: prevCompanies is not iterable
因為我相信companies
列表最初是空的。
我嘗試通過使用concat
方法來使用另一種方法,但是companies
列表保持為空並且no companies found
的消息。
下面是Home
的源代碼
const Home = () => {
const [page, setPage] = useState(1); //In order to avoid showing "no companies found" initially
const [isLoading, setIsLoading] = useState(true);
const [companies, setCompanies] = useState([]);
const [isError, setIsError] = useState(false);
const [hasMore, setHasMore] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
setIsError(false);
try {
const fetchedCompanies = await fetchFeedData(page);
setCompanies((prevCompanies=>{prevCompanies.concat(fetchedCompanies)})); //problem here
setHasMore(fetchedCompanies.length > 0)
} catch (e) {
setIsError(true)
setHasMore(false);
}
setIsLoading(false)
}
fetchData();
}, [page])
return (
<div>
<ScrollToTopBtn />
<Helmet>
<title>{stackinfo.title} - {home.title}</title>
</Helmet>
<HomeHeader />
{
isLoading ? (<LoadingSpinner />) :
isError ? (<ErrorBoundary message={somethingWrongError.message}></ErrorBoundary>) :
<CompanyList companies={companies} ></CompanyList>
}
<Container className={"mt-5"}>
<Row>
<Col sm={12}>
{(!isLoading && !isError && hasMore) &&
<CustomBtn
ButtonText={showMoreBtnText.message}
onClick={() => { console.log("Need to increment number of pages") }}
></CustomBtn>}
</Col>
</Row>
</Container>
</div>
)
}
在撥打 API 電話后,我試圖檢查fetchedCompanies
和companies
const fetchedCompanies = await fetchFeedData(page);
//Returning new array containing previous companies and recent fetchedCompanies
console.log(fetchedCompanies);
setCompanies((prevCompanies=>{prevCompanies.concat(fetchedCompanies)}));
console.log(companies);
fetchedCompanies
記錄了一個包含 9 個元素的數組,而上面提到的companies
記錄了空數組[]
。
對不起,如果我錯過了什么,我對 React 還是個新手。
您可以在下面執行此操作以更新
setCompanies([...companies, ...fetchedCompanies])
如果獲取的公司是全新的數組,包含所有以前的記錄,那么就在下面做;
setCompanies([...fetchedCompanies]);
//OR
setCompanies(fetchedCompanies);
如果您有空字符串,請在下面執行此操作
setCompanies([...companies, ...fetchedCompanies.filter(com => !com)]);
這是試圖改變 state,而不是返回一個新的 state(或者你可能只是忘記了return
關鍵字?):
setCompanies((prevCompanies=>{prevCompanies.concat(fetchedCompanies)}));
您之前的嘗試更接近:
setCompanies(prevCompanies=>{return [...prevCompanies, fetchedCompanies]});
但是,如果fetchedCompanies
也是一個數組,那么您就忘記了它的擴展運算符:
setCompanies(prevCompanies=>{return [...prevCompanies, ...fetchedCompanies]});
如果沒有它,結果數組充其量只會很奇怪。
你也可以稍微簡化一下:
setCompanies(prevCompanies=>[...prevCompanies, ...fetchedCompanies]);
如果您不希望這些調用完全重疊,您可能會簡化很多:
setCompanies([...companies, ...fetchedCompanies]);
如果在那之后仍然有一個空字符串,那么數據似乎是一個空字符串。 在那種情況下,您必須手動過濾掉它,如果過濾行為可能會與您那里的邏輯 rest(例如, hasMore
值)混淆,那么您在哪里進行過濾實際上取決於您。 但是您可以隨時將 append .filter()
轉換為結果數組。 獲取時,更新 state 時,甚至只是渲染時。
您最好查看空字符串的來源並嘗試解決該問題,但如果您只是想刪除空字符串,請使用以下命令。
prevCompanies.concat(fetchedCompanies).filter(Boolean)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.