Функция карты не запускается после того, как useEffect устанавливает состояние в непустой список

Я пытаюсь получить некоторые данные с моего сервера node js, который возвращает мне массив. Получив этот массив, я хочу отобразить его и отобразить несколько итераций одного и того же компонента с этими данными. Однако функция карты не запускается, так как начальное значение состояния, которое я установил, было пустым массивом. Мой вопрос: почему функция карты не работает после изменения состояния в функции useEffect? Вот код:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
        const fetchData = await fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        })

        const jsonFetch = await fetchData.json();
        setGroupData(jsonFetch.groupData);
    }

    func();
}, [])

return (
    {groupData.map((elem) => {
        <Card data = {elem} />
    })}
)

Но карт просто не видно. Я могу использовать console.info, чтобы увидеть данные, поступающие в реакцию, как и ожидалось. Я также попытался изменить второй параметр функции useEffect на [groupData] вместо []. Но это все еще не работает. Любая помощь будет оценена по достоинству. Благодарю вас!

🤔 А знаете ли вы, что...
JavaScript поддерживает объектно-ориентированное программирование.


24
3

Ответы:

Решено

Кажется, вы ничего не вернули из метода .map(). Попробуйте сделать так (убрать фигурные скобки):

return (
    {groupData.map((elem) => <Card data = {elem} /> )}
)

Также рекомендуется добавлять уникальные ключи при рендеринге списка (https://reactjs.org/docs/lists-and-keys.html)


Когда вы используете функции async, вы должны продолжать свою логику только тогда, когда запрошенный контент будет доставлен. Вы должны реализовать функцию then, как в примере ниже:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
        fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        }).then(response => {
           setGroupData(response.json().groupData);
        }).catch(e => {
            // Ops, there's a problem...
        });
    }
    func();
}, [])

return (
    {groupData.map((elem) => {
        <Card data = {elem} />
    })}
)

[] с


Поскольку у groupData еще нет данных при рендеринге компонента. Попробуйте этот код ниже:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
       try{
           const fetchData = await fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        })

        const jsonFetch = await fetchData.json();
        setGroupData(jsonFetch.groupData);
        } catch (err){console.info(err)}; //<== Add try...catch to avoid app crash and catch error!          
    }

    func();
}, [])

return (
    {groupData?.map((elem, index) => {
        <Card key = {index} data = {elem} />
    })} //<== add "?" after groupData and key attribute in <Card /> !
)