开发者问题收集

为什么我的 useState 值在获取后未定义?似乎 useState 不起作用 [重复]

2024-01-08
90
import React, { useEffect, useState } from 'react';

function MainContent() {
    const [objectsArr, setObjectsArr] = useState(null);

    useEffect(() => {
        async function fetchMyAPI() {
            let response = await fetch('http://localhost:3030/pickedObjects')

            response = await response.json();
            setObjectsArr(response)
        }
        fetchMyAPI()
    }, [])

    const contentDiv = document.getElementsByClassName('content')[0];

    return (
        <ul className="content row">
            {objectsArr.map((item) => {
                return (
                    <ContentItem className="item" item={item} />
                )
            })}
        </ul>
    );
}

export default MainContent;

我尝试使用调用提取的 useEffect 来渲染元素数组,然后我使用 .map() 直接渲染它们

因此,当我尝试运行此程序时,我收到错误:

Uncaught TypeError: Cannot read properties of null (reading 'map')

这是 setObjectsArr 的初始值。那么 useEffect 中的 setObjectsArr(response) 是否未设置,或者是否设置得太早?

我该如何修复?

我几乎尝试了所有方法,但找不到它不起作用的原因。提取本身没问题,它返回一个合适的值,但 useState 没有设置它。

2个回答

Cannot read properties of null (reading 'map')

因为您将初始值定义为 null

const [objectsArr, setObjectsArr] = useState(null);

并尝试对其调用 .map()

objectsArr.map((item) => {

这一切都发生在任何 API 交互发生之前。API 调用的结果可能确实是一个数组(我们不知道,但大概这就是您所期望的),并且状态将在稍后更新为该值。但在此之前,您需要一个可以无错误呈现的组件。

听起来空数组是更合理的默认值:

const [objectsArr, setObjectsArr] = useState([]);

或者,在使用它之前检查该值。例如,使用可选链接:

objectsArr?.map((item) => {

或者检查是否为假值:

objectsArr && objectsArr.map((item) => {
David
2024-01-08

好的,所以我重构了所有内容,不确定这是否是正确的方法,但工作正常:

const [renderedObjects, setRenderedObjects] = useState([]);

useEffect(() => {
    getData('http://localhost:3030/pickedObjects');
}, []);

const getData = async (apiUrl) => {
    const data = fetch(apiUrl)
        .then((response) => {
            return response.json();
        })
        .then(json => {
            setRenderedObjects(json.map((item) => {
                return (
                    <ContentItem className="item" item={item} />
                )
            }))
        });
}

const contentDiv = document.getElementsByClassName('content')[0];

return (
    <ul className="content row">
        {renderedObjects}
    </ul>
);

现在,我的 setRenderedObjects useState 值直接在提取中设置。

Denys
2024-01-08