Задать вопрос
@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". Но это детали уже
  • Вопрос задан
  • 274 просмотра
Подписаться 1 Простой 3 комментария
Решения вопроса 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.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
ITK academy Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽