首页 > 解决方案 > 使用异步函数返回 axios 数据的 REACT createContext

问题描述

我正在创建 React 上下文,但它返回了一个承诺。在文件 playlistcontext.js 我有以下代码:

import React, { useEffect } from 'react';
import YouTube from '../services/youtube';

const playlistsData = YouTube.getPlaylists();
// console.log(playlistsData);
const PlaylistsDataContext = React.createContext(playlistsData);

const PlaylistsDataProvider = (props) => {
    
    const [playlists, setPlaylists] = React.useState(playlistsData);

    useEffect(() =>{
        const playlistsData = YouTube.getPlaylists();
        console.log(playlistsData);
        setPlaylists(playlistsData);
    },[])

    return <PlaylistsDataContext.Provider value={[playlists, setPlaylists]}>{props.children}</PlaylistsDataContext.Provider>;
}

export {PlaylistsDataContext, PlaylistsDataProvider};

在 youtube.js 文件中,我像服务一样使用它,我有下面的代码。在此函数中,console.log(result.data) 返回正确的数据。

import axios from 'axios';
import { YOUTUBE_API } from '../config/config';

function Youtube() {

    const handleError = (resp) => {
        
        let message = '';

        switch (+resp.status) {
            case 401:
                message = resp.data.error;
                break;
            default:
                message = 'general error';
        }

        return message;
    }

    const getPlaylists = async () => {

        try {
            const result = await axios.get(YOUTUBE_API + '');
            
            return result.data;
        } catch(e) {
            return Promise.reject(handleError(e.response));
        }
        
    }

    return {
        getPlaylists
    }
}

const ytMethod = Youtube();
export default ytMethod;

然后,我有一个容器“tutorialcontainer.js”,其中包装了一个组件:

import React, {useState} from 'react';
import { PlaylistsDataProvider } from '../containers/playlistscontext';
import Tutorials from '../components/tutorials';

const TutorialsContainer = (props) => {

    return (
        <PlaylistsDataProvider>
            <Tutorials />
        </PlaylistsDataProvider>
    );
}

export default TutorialsContainer;

在最后一个文件 tutorials.js 我有组件。在这个文件中,console.log(playlist) 给我一个承诺。

import React, {useState, useEffect} from 'react';
import SectionBoxPlaylist from '../components/html_elements/card_playlist';
import Header from '../components/header';
import { PlaylistsDataContext } from '../containers/playlistscontext';

const Tutorials = (props) => {

    const [playlists, setPlaylists] = React.useContext(PlaylistsDataContext);

    return (
        <div className="app-container">
            <Header />
            <div className="section section-one text-center">
                <div className="section-content">
                    <div className="section-box-items">
                        {   
                            Object.keys(playlists).map((item) => {
                                return <SectionBoxPlaylist key={item} id={item} info={playlists[item]} />
                            })
                        }
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Tutorials;

你能帮我解释一下为什么吗?谢谢!

标签: javascriptreactjs

解决方案


setPlaylists之后立即调用YouTube.getPlaylists()

useEffect(() => {
  const playlistsData = YouTube.getPlaylists();
  console.log(playlistsData); // playlistsData is not fetched
  setPlaylists(playlistsData);
},[])

您应该能够使用.then()

YouTube.getPlaylists().then(response => {
  console.log(response);
  setPlaylists(response);
});

您还可以在内部创建异步函数useEffect()

useEffect(() => {
  const getYTPlaylist = async () => {
    const playlistsData = await YouTube.getPlaylists();
    console.log(playlistsData);
    setPlaylists(playlistsData);
  }
  
  getYTPlaylist();
},[])

推荐阅读