簡體   English   中英

React - 使用 useState 鈎子用新值更新以前的數組

[英]React - Updating previous array with new values using useState hook

我創建了一個包含三個組件HomeHeaderCompanyListScrollToTopBtn的主頁。 專注於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 電話后,我試圖檢查fetchedCompaniescompanies

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM