@Danila232

Как взять данные из fetch-запроса в React-компоненте?

У меня есть компонент DataList и функция getCharackters().

Функция - делает fetch-запрос к АPI-шке и по задумке возвращает объект с персонажами(ну она и возвращает, тут всё норм).
А компонент в свою очередь вызывает внутри себя эту функцию, принимает из неё объект персонажей, записывает их в свой начальный State - и уже потом берёт их и отрисовывает на странице(код отрисовки закоменчен, т.к ошибка не в этом)

// DataList - принять+отрисовать
import {useState, useEffect} from 'react';
import './charList.scss';

import getCharackters from '../../api/data.jsx';  // функция, делающая запрос

const CharList = (props) => {


    const [dataCards, setDataCards] = useState(getCharackters())  // useState(getCharackters().data) - вызовет undefined, а .data.results - ошибку

    console.log(getCharackters())
    
    // const cardDataList = Array.from(dataCards);  
    // const cards = cardDataList.map(card => {
    // let [name, description, image] = [card.name, card.description, card.thumbnail.path + '.' + card.thumbnail.extension]
    //     return (
    //             <li 
    //                 className="char__item" 
    //                 key={card.id} 
    //                 onClick={() => {props.setCharacterId(card.id)}}
    //                 > 
    //                 <img src={image} alt="abyss"/>
    //                 <h3 className="char__name">{name}</h3>
    //                 <p className='char__descr'>{description}</p>
    //             </li>
    //     )
    // }) 

    return(
        <ul className="char__list">
            {/* {cards} */}
        </ul> 
    )

}

export default CharList;


//data - функция fetch-запроса
let getResource = async (url) => {
    const response = await fetch(url)

    if(!response.ok){
        throw new Error(`Could not fetch ${url} with ${response.status} status`)
    } 

    return await response.json()
}

let getCharackters = () => {
    return getResource('https://gateway.marvel.com:443/v1/public/characters?limit=6&apikey=5495b7aa6d32f3cbab5c21680fb7e17c')
}

export default getCharackters;


663537fff261f555628335.png

Ну и я если честно не пойму, как мне взять данные из запроса, потому что мне почему то в 11й/13й строчках(DataList) приходит не готовый объект, а Promise. И я не понимаю, почему мне приходит Promise?? А не его результат. Мне нужно обратиться как useState(getCharackters().data.results), но так не работает

*Скорее всего у меня просто мало знаний про Промисы - например я не понимаю, почему в нём выводится сразу 2 его состояния - сначала написано что он "pending", потом написано что "fullfiled". Но это детали уже
  • Вопрос задан
  • 184 просмотра
Решения вопроса 1
Elaryks
@Elaryks
У вас используется асинхронная функция, которая возвращает промис. Соответственно, результата её выполнения нужно сначала дождаться. Поэтому getCharacters().data === undefined, и уже даже из этого очевидно, что getCharacters().data.results приведёт к ошибке, т.к. это попытка обратиться к свойству у undefined.

Вашу проблему можно решить, используя хук useEffect с пустым массивом зависимостей, благодаря чему он сработает только при монтировании/размонтировании компонента:

const [dataCards, setDataCards] = useState([]);

useEffect(() => {
    getCharacters().then((data) => setDataCards(data));
}, []);


Здесь мы изначально инициализируем dataCards как пустой массив (что логично, ведь данных пока что нет). При монтировании компонента сработает useEffect, внутри него мы получим данные и уже их сможем использовать в dataCards.

Кстати, обратите внимание, что вы указали настоящий ключ API.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы