简体   繁体   中英

Can't set state in React using hooks

I'm working on a fairly simple app to learn React Hooks and I got stuck. I want to fetch and display data from specific Spotify playlist. So far, this is my component:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function SongsList() {
    const [data, setData] = useState({ songs: [] });
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        const fetchData = async () => {
            setIsLoading(true);
            const result = await axios.get('https://api.spotify.com/v1/playlists/37i9dQZEVXbMDoHDwVN2tF/tracks', {
                    headers: {
                        Authorization: 'Bearer sometoken'
                    }
                }
            )
            setData(result.data.items);
            console.log(result.data.items);
            setIsLoading(false);
        }
        fetchData();
    }, [])

    return (
        <div>
            {isLoading ? (
                <div>Loading...</div>
            ) : (
                <div>
                    {data.songs.map(song => (
                        <li key={song.track.id}>
                            <p>{song.track.artist}</p>
                        </li>
                    ))}
                </div>
            )
            }
        </div>
    )
}

export default SongsList;

This code throws an error saying TypeError: data.songs is undefined and I can't understand why is that. Please note that in my fetchData function I have a log from my console tu ensure that I at least fetch any data: console.log(result.data.items); . It gives me the correct output: 我的控制台日志输出

But my data in useState output seems to be never setted or setted wrong. Can you please help me to understand what is wrong about my code? Thanks in advance!

You are not setting the data right way. You have declared data as an object which contains songs . You should set songs like:

setData({ songs: result.data.items });

And this will work for you.

Considering that your component is mounted before the request is made, you should also check for the presence of the data before rendering. like below:

{ data && data.songs.map(song => (
   <li key={song.track.id}>
       <p>{song.track.artist}</p>
   </li>
   )) 
}

Change to this setData({songs: result.data.items});

Because you are defining your songs array in object.

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