简体   繁体   English

为什么我得到 Object 作为 React 孩子无效

[英]Why am I getting Object are not valid as a React child

I am using a Spotify API to fetch songs and I am trying to display the first song for testing.我正在使用 Spotify API 来获取歌曲,我正在尝试显示第一首歌曲进行测试。

I am trying to display the first song as text but currently I am getting the error "Objects are not valid as a React child (found: Object with keys {_U, _V, _W, _X}). If you meant to render a collection of children use a array instead.我正在尝试将第一首歌曲显示为文本,但目前我收到错误“对象作为 React 子项无效(找到:Object,键为 {_U、_V、_W、_X})。如果您打算渲染集合的孩子改用数组。

I am confused as I am just trying to the first thing from the JSON and display it as a text on the stats screen我很困惑,因为我只是想从 JSON 开始做第一件事,并将其显示为统计屏幕上的文本

import React, {useState} from "react";
import axios from "axios";
import { getSpotifyToken } from "../../hooks/spotifyAuth";

const getTopTracks = async () => {
  //Getting spotify token
  const spotifyToken = getSpotifyToken();
  console.log("Getting access Token for TopSongs:", spotifyToken );

  // const [songName, setSongName] = useState("");

  const api_url = "https://api.spotify.com/v1/me/top/tracks?time_range=short_term&limit=5";
  // const api_url = "https://api.spotify.com/v1/me/top/artists?time_range=short_term&limit=1&offset=5";
  
  // console.log(api_url);
  try{
    const response = await axios.get(api_url, {
      headers: {
        'Authorization': `Bearer ${spotifyToken}`
      }
    });

    const myJSON = response.data.items[0].name.toString();
    console.log("My JSON:", myJSON); //this just prints the song name
    return myJSON;
  }catch(error){
    console.log(error);
  }  
};

const StatsScreen = ({ navigation }) => {
  const topSong = getTopTracks();


  return (
    <View>
      <Text>StatsScreen</Text>
      <Text>{topSong}</Text>
    </View>
  );
};

export default StatsScreen;

Because topSong is a promise, not a string.因为topSong是 promise,而不是字符串。 async functions always return promises ( more here ). async函数总是返回承诺( 更多在这里)。

If you want StatsScreen to retrieve the top song, you'll need to make it stateful, since initially it won't have a song to show:如果您希望StatsScreen检索热门歌曲,则需要使其有状态,因为最初它不会显示歌曲:

const StatsScreen = ({ navigation }) => {
    const [topSong, setTopSong] = useState(null);
    useEffect(() => {
        getTopSongs()
        .then(setTopSong)
        .catch((error) => {
            // ...handle/report error...
        })
    }, []); // <== Empty deps array = only on mount

    return (
        <View>
            <Text>StatsScreen</Text>
            {topSong && <Text>{topSong}</Text>}
        </View>
    );
};

That fetches the top song on mount via useEffect , and stores the result as state using useState .它通过useEffect获取 mount 上的第一首歌曲,并使用 useState 将结果存储为useState I've had it not render the second Text at all when it doesn't have one, but of course you can tweak that as desired, for instance:当它没有第二个文本时,我根本没有渲染第二个Text ,但是当然您可以根据需要进行调整,例如:

    return (
        <View>
            <Text>StatsScreen</Text>
            <Text>{topSong ? topSong : "Loading top song..."}</Text>
        </View>
    );
};

A more robust version can use an AbortController ( in axios v0.22.0 and up ; for earlier versions, use the deprecated axios-specific CancelToken ) to cancel the outstanding HTTP request if the component is unmounted while it's running:更健壮的版本可以使用AbortController在 axios v0.22.0 及更高版本中;对于早期版本,使用已弃用的 axios 特定的CancelToken )来取消未完成的 HTTP 请求,如果组件在运行时被卸载:

const getTopTracks = async (signal) => {
    //                      ^^^^^^ <====
    // ...
    try {
        const response = await axios.get(api_url, {
            signal, // <====
            headers: {
                Authorization: `Bearer ${spotifyToken}`,
            },
        });
        // ...
    } catch (error) {
        console.log(error);
    }
};

const StatsScreen = ({ navigation }) => {
    const [topSong, setTopSong] = useState(null);
    useEffect(() => {
        const controller = new AbortController();   // <====
        getTopSongs(controller.signal)              // <====
            .then(setTopSong)
            .catch((error) => {
                // ...handle/report error...
            });
        return () => {                              // <====
            // Called on unmount                    // <====
            controller.abort();                     // <====
        };
    }, []); // <== Empty deps array = only on mount

    return (
        <View>
            <Text>StatsScreen</Text>
            {topSong && <Text>{topSong}</Text>}
        </View>
    );
};

Your getTopTracks() is returning a promise as you have not await-ed the function call.您的getTopTracks()正在返回 promise 因为您尚未等待 function 调用。 Also you haven't called the API at the right place.此外,您还没有在正确的位置调用 API。

API calls are asynchronous and so the data comes after the component has rendered. API 调用是异步的,因此数据是在组件渲染之后出现的。 So the basic flow for any API call like this has to be:因此,任何像这样的 API 调用的基本流程必须是:

  1. Make a state variable to store the data.创建一个 state 变量来存储数据。

     const [topSong, setTopSong] = useState("");
  2. Call the API in a useEffect (If the data is to be fetched only once, you may use an empty dependency array)在 useEffect 中调用useEffect (如果数据只获取一次,可以使用空的依赖数组)

     useEffect(() => { const fetchTopSong = async () => { const response = await axios.get(...); setTopSong(response.data.items[0].name); } fetchTopSong(); }, []);
  3. Use this state in your render method now.现在在您的渲染方法中使用这个 state。

     return ( <View> <Text>StatsScreen</Text> <Text>{topSong}</Text> </View> );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使我没有尝试渲染对象,获取对象也不能作为 React 子错误有效 - Getting a Objects are not valid as a React child error even though I am not trying to render an object 为什么我收到警告 - 函数作为 React 孩子无效。 ……? - why I am getting warning-Functions are not valid as a React child. …? 为什么我得到 Functions are not valid as a React child? - Why I'm getting Functions are not valid as a React child? 为什么我会收到关于作为 React Child 的函数的警告 - Why am I getting warning for functions as a React Child on this 对象作为 React 子对象无效(找到:[object Promise])。 但我没有回报承诺? - Objects are not valid as a React child (found: [object Promise]). But I am not returning a promise? 映射API响应时获取“对象作为React子无效” - Getting “Object are not valid as a React child” when mapping API response 为什么当我按下可触摸的不透明度时,它会给出对象无效的错误作为反应孩子 - Why does it give a error of object are not valid as react child when I press touchable opacity 当我将函数传递给React.js的子组件时,为什么会出现未捕获的TypeError? - Why am I getting an uncaught TypeError when I pass a function to a child component in React.js? “警告:尝试删除不存在的子项”为什么我在React Native中收到此警告? - “Warning: Trying to remove a child that doesn't exist” Why am I getting this warning in React Native? 错误:Object 作为反应孩子无效 - Error : Object are not valid as a react child
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM