Перескакивание массивов в машинописном тексте

#javascript #arrays #reactjs #typescript

Вопрос:

Кажется, я не могу разобраться в циклических массивах/объектах. Я довольно часто застреваю в них. Как здесь, например, я не могу повторить данные из api, я получаю trending is not a function ошибку. Может ли кто-нибудь помочь мне исправить это и дать мне какое-нибудь хорошее направление, чтобы лучше зацикливаться

Интерфейс

 export interface Item {
    id: string;
    name: string;
    symbol: string;
    market_cap_rank: number;
    thumb: string;
    large: string;
    score: number;
}

export interface Coin {
    item: Item;
}

export interface ResponseObject{
    coins: Coin[];
   
}


 

Код

 import React, { useEffect, useState} from 'react'
import axios from  'axios'
import { ResponseObject } from '../interfaces';
const TRENDING = 'https://api.coingecko.com/api/v3/search/trending'
const Home:React.FC= () => {
  
    const [trending, setTrending ] = useState<ResponseObject[]>([])
    useEffect(()=>{
        axios
        .get<ResponseObject[]>(TRENDING)
        .then((response) => 
        {setTrending(response.data); 
        console.log(response) })
        .catch(err =>
        { console.log(err); })
    },[])

    return (
        <div>  
           {trending.map(trend =>
           (<div key={trend.item.id}>{trend.item.name}</div>))}
        </div>
    )
}

export default Home
 

API

 {
   "coins":[
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
   ],
   "exchanges":[]
}
 

Комментарии:

1. разве вы не должны переходить response.data.coins в setState?

Ответ №1:

Я предполагаю, что вы, вероятно, установили объект в качестве трендового, а не массива. response.data должен возвращать объект, который будет похож на ваш API.

 // response.data should return this object.
{
   "coins":[
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
   ],
   "exchanges":[]
}
 

Вы должны установить response.data.coins в качестве тенденции, которая вернет массив.

 [
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
]
 

Комментарии:

1. Я получаю свойство «монеты», которого не существует в объекте типа ответа

2. Не могли бы вы, пожалуйста console.log(response) , поделиться здесь?

3. держи, извини, что меня здесь не было. imgur.com/POxMzvY

4. @Текила, я сделал для тебя песочницу: codesandbox.io/s/api-coingecko-1qnu9

5. response.data имеет тип ResponseObject (как вы указали в axios.get ). response.data.coins is Coins[] (массив монет). И я написал setTrending(response.data.coins); в API success. Это означает, что я устанавливаю response.data.coins (типа Coin[] ) в состояние, т. Е. trending . Итак, мне нужно сказать useState , что я буду устанавливать Coin[] тип данных вместе с вами. Вот почему я написал useState<Coin[]>([]); .

Ответ №2:

Проблема не имеет ничего общего с цикличностью.

Вы вызываете setTrending что-то, что не является массивом. вот почему вы получаете trending.map is not a function .

Ваш API напрямую возвращает не массив, а объект с двумя ключами, каждый из которых содержит массив.

В вашем случае вы должны позвонить setTrending(response.data.coins) .

ИЗМЕНИТЬ: вы также должны исправить свое ResponseObject использование:

 const [trending, setTrending ] = useState<Coin[]>([]);

useEffect(()=> {
    axios
      .get<ResponseObject>(TRENDING)
      .then((response) =>  {
        setTrending(response.data.coins); 
    })
    .catch(err => console.log(err));
},[]);
 

Комментарии:

1. Я получаю свойство «монеты», которого не существует в объекте типа ответа