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();
},[])