I’m creating React context but it returns a promise. In the file playlistcontext.js I’ve the following code:
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};
In the file youtube.js, that I use it like a service, I’have the code below. In this function a console.log(result.data) return me the correct 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;
then, I have a containers “tutorialcontainer.js” in which I’ve wrapped a component:
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;
In the last file tutorials.js I have the component. In this file the console.log(playlist) returns me a promise.
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;
Can you help and explain me why? Thank you!
Advertisement
Answer
setPlaylists
is called immediately after YouTube.getPlaylists()
.
useEffect(() => { const playlistsData = YouTube.getPlaylists(); console.log(playlistsData); // playlistsData is not fetched setPlaylists(playlistsData); },[])
You should be able to use .then()
:
YouTube.getPlaylists().then(response => { console.log(response); setPlaylists(response); });
You can also create async function inside useEffect()
:
useEffect(() => { const getYTPlaylist = async () => { const playlistsData = await YouTube.getPlaylists(); console.log(playlistsData); setPlaylists(playlistsData); } getYTPlaylist(); },[])