Реакция: проблема с получением нескольких запросов - PullRequest
0 голосов
/ 21 апреля 2020

Так что у API, с которым я работаю, нет одного источника, чтобы получить всех покемонов, но он имеет ссылки на каждого с их идентификатором в качестве параметра. Я использую для l oop, чтобы получить все запросы. Я делал это синхронно, используя asyn c await, но это было очень медленно.

Код не работает. Он получает запросы, но не обновляет карту должным образом. Он только регистрирует текущую карту, прежде чем получает запросы.

import React from 'react'
import axios from 'axios'

//Defines what a Pokemon has
interface Pokemon {
    name: string,
    id: number,
    sprite: string
}

const PokemonList2: React.FC<{}> = (props) => {
    //The state is a Map of pokemon. Key is the Pokemon's name, value is a Pokemon object
    const [pokemonMap, setPokemonMap] = React.useState<Map<string, Pokemon>>(new Map<string, Pokemon>())

    //Handles API request
    React.useEffect(() => {
        //Sets the temporary map equal to the state's map
        let tempPokemonMap: Map<string, Pokemon> = pokemonMap

        //loops through pokemon
        for (let i = 1; i <= 50; i++){
            //says it's loading
            console.log('loading...')

            //gets the request
            axios.get('https://pokeapi.co/api/v2/pokemon/' + i)
                .then(res => {
                    //adds the new pokemon to the map
                    tempPokemonMap.set(res.data.name, {
                        name: res.data.name,
                        id: res.data.id,
                        sprite: res.data.sprites.front_default
                    })

                    //Sets the state map to the temp map
                    setPokemonMap(tempPokemonMap)

                    //logs that is was added
                    console.log(`Added ${ res.data.id } : ${ res.data.name }`)
                })
        }

    }, [setPokemonMap, pokemonMap])

    //logs the current map
    console.log(pokemonMap)

    //Gets JSX from the map
    let pokemonJSX: JSX.Element[] = []
    pokemonMap.forEach(pok => {
        pokemonJSX.push(
            <div key={ pok.id } style={{ textAlign: "center" }}>
                <p>{ pok.name }</p>
                <img src={ pok.sprite } alt={ pok.name }/>
            </div>
        )
    })

    //Prints the JSX
    return (
        <div className="container">
            { pokemonJSX }
        </div>
    )
}

export default PokemonList2

1 Ответ

0 голосов
/ 21 апреля 2020

В этом случае ваша проблема заключается в том, что когда вы назначаете tempPokemonMap для pokemonMap, вы фактически не копируете значение pokemonMap в вашу переменную, а просто передаете ссылку. Когда вы позже попытаетесь обновить свое состояние, вы передаете ту же ссылку на объект, который уже находится в состоянии, именно поэтому React не обнаруживает никаких изменений и почему он не перерисовывается.

Кроме того, я бы также предложил, как упоминал d3bgger, выполнить все ваши запросы, а затем обновить состояние. Как с точки зрения производительности, так и опыта пользователя.

...