Search code examples
reactjsreact-hooksuse-effect

I am confused on how I would push to an array using useState?


When I used the standard setDate(prev => ({...prev, data}) to try and push to an array I just overwrite to the previous array, how would I push to an array using useState?

my code:

const LightMode = () => {
    const [data, setData] = useState([])

    useEffect(() =>{
        axios.get('https://restcountries.com/v3.1/all').then(res=>{
            res.data.forEach(country =>{
                //console.log(country)
                setData((prev) => ([{...prev,
                    name: country.name.common,
                    population: country.population,
                    region: country.region,
                    capital: country.capital,
                    image: country.coatOfArms.png}]))
            })
        })
    }, [])

    console.log(data)

    return(
        <div>
            <NavigationBar />
            <div className='temp'>
                <Card className='country-cards'>
                    <Card.Img variant='top' src={data?[0].image: null}/>
                    <Card.Body>
                        <Card.Title></Card.Title>
                    </Card.Body>
                </Card>
            </div>
        </div>
    )
}

export default LightMode;

but all this does is overwrite to the new item in the array and I want to push or append an new item to the array, I want to know how I can accomplish this? Any help is wanted.

pic


Solution

  • You just need to move ...prev a bit "up"

    setData((prev) => [
      ...prev,
      {
        name: country.name.common,
        population: country.population,
        region: country.region,
        capital: country.capital,
        image: country.coatOfArms.png
      }
    ]);
    

    Also, you can prepare data to insert and get rid of .forEach

    useEffect(() => {
      axios.get("https://restcountries.com/v3.1/all").then((res) => {
        const toInsert = res.data.map((x) => ({
          name: x.name.common,
          population: x.population,
          region: x.region,
          capital: x.capital,
          image: x.coatOfArms.png
        }));
    
        setData((prev) => [...prev, ...toInsert]);
      });
    }, []);