简体   繁体   中英

React .map not rendering

I've done a API call to get some datas then store it in an array and do a.map in the return

This is the code if you guys have any ideas it's been 2 hours that i'm stuck on this:(

import {useEffect, useState} from 'react';
import {useParams} from "react-router-dom";
import axios from "axios";


const CharacterScreen = () => {
    const params = useParams()
    const [character, setCharacter] = useState([]);
    const [starships, setStarships] = useState([]);


    useEffect(() => {
        axios.get(`https://swapi.dev/api/people/?search=${params.character}`)
            .then((r) => {
                setCharacter(r.data.results[0])
                getStarships(r.data.results[0])
            })
            .catch((e) => console.log(e))

        const getStarships = (data) => {
            let array = []
            data.starships.forEach(element => {
                axios.get(element)
                    .then((r) => {
                        array.push(r.data)
                    })
                    .catch((e) => console.log(e))
            })
            console.log(array)
            setStarships(array)
        }
    }, []);

    console.log(starships)
    return (
        <div>
            <p>{character.name}</p>
            <p>{character.eye_color}</p>
            <p>{character.birth_year}</p>
            <p>{character.gender}</p>
            <p>{character.created}</p>
            <p>{character.edited}</p>
            {starships.map((element) => {
                console.log('ok')
                return (
                    <p key={element.key}>{element.name}</p>
                )
            })}

        </div>
    )


}

This is the.log of starships:

文本

This is my return:

文本 Any help would be apréciated

Use spread operator:

useEffect(() => {
        axios.get(`https://swapi.dev/api/people/?search=${params.character}`)
            .then((r) => {
                setCharacter(r.data.results[0])
                getStarships(r.data.results[0])
            })
            .catch((e) => console.log(e))

        const getStarships = (data) => {
            let array = []
            data.starships.forEach(element => {
                axios.get(element)
                    .then((r) => {
                        array.push(r.data)
                    })
                    .catch((e) => console.log(e))
            }) 
            setStarships([...array]) <=== //spread opeator
        }
    }, []);

The code inside your forEach will run asynchronously. You would have to wait for all that data to be actually populated in your array . async/await pattern + Promise.all(..) would be a good bet here and can be done like so:-

const getStarships = async (data) => {
  let array = await Promise.all(data.starships.map(element => {
    return axios.get(element)
      .then((r) => {
        return r.data
      })
      .catch((e) => console.log(e));
  }))
  setStarships(array);
}

Currently in your code by the time you do setStarships(array) , array will be empty ie [] .

Check this codesandbox where it's working:-

编辑 SWAPI - StackOverflow

Note:- Don't pay attention to element.replace code, thats just for making secure requests

You have a syntax error, you should replace your bracket with a parenthesis like following:

 {starship && starships.map((element) => (//here console.log('ok') return ( <p key={element.key}>{element.name}</p> ) )//and here)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM