繁体   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