无法使用钩子在React中设置状态

时间:2020-01-26 15:34:39

标签: reactjs spotify

我正在使用一个相当简单的应用程序来学习React Hooks,但是我陷入了困境。我想从特定的Spotify播放列表中获取并显示数据。到目前为止,这是我的组件:

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;

此代码引发错误,提示TypeError: data.songs is undefined,我不明白为什么会这样。请注意,在我的fetchData函数中,我从控制台获得了一条日志,以确保至少获取任何数据:console.log(result.data.items);。它给了我正确的输出: my console log output

但是我在data中的useState输出似乎从未设置过或设置错误。您能帮我了解我的代码有什么问题吗?预先感谢!

3 个答案:

答案 0 :(得分:2)

您未正确设置data。您已将data声明为包含songs的对象。您应将songs设置为:

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

这将为您工作。

答案 1 :(得分:1)

考虑到在发出请求之前已安装组件,您还应该在渲染之前检查数据是否存在。如下所示:

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

答案 2 :(得分:0)

更改为此setData({songs: result.data.items});

因为要在对象中定义songs数组。