skip to Main Content

I’m new to react and I’m facing a problem regarding useContext.

I want to connect to some API and get some data from there, and store it in a context.

So, here is the MovieContextProvider.jsx file that is responsible for this:

import React, { useState, createContext, useEffect } from 'react';
import axios from 'axios';


const MovieContext = createContext();

const URL = "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=9813ce01a72ca1bd2ae25f091898b1c7";

function MovieContextProvider({ children }) {

    const [movieData, setMovieData] = useState();

    useEffect(() => {

        axios.get(URL)
            .then((response) => setMovieData(response.data.results))
            .catch((error) => console.log(error));

    }, []);


    return (

        <MovieContext.Provider value={movieData}>
            {children}
        </MovieContext.Provider>

    );
}

export default MovieContextProvider;

Now, I’m using this context in another file Movies.jsx

import React from 'react';
//import MovieCard from '../Components/MovieCard';

import { useContext } from 'react';

import MovieContext from '../Contexts/MovieContextProvider';

function Movies() {

    const movieData = useContext(MovieContext);

    console.log(movieData); //Here I'm checking firstly if the data
                           //received properly from the context

    return (

        <div>

            Movies...
            
        </div>
    );
}

export default Movies;

Lastly, this is my App.js file

import React from 'react';
import './App.css';

import { BrowserRouter, Routes, Route } from "react-router-dom";
import NavBar from './Components/NavBar';
import Home from './Components/Home';
import AboutUs from './Components/AboutUs';
import Movies from './Components/Movies';
import MovieContextProvider from './Contexts/MovieContextProvider';


function App() {
  return (
    <div className="App">

      <MovieContextProvider>
        <BrowserRouter>
          <NavBar></NavBar>

          <Routes>
            <Route path='/Movies' element={<Movies></Movies>}></Route>

            <Route path="/Home" element={<Home></Home>}></Route>

            <Route path="/AboutUs" element={<AboutUs></AboutUs>}></Route>

          </Routes>
        
        </BrowserRouter>
        
      </MovieContextProvider>
      


    </div>
  );
}

export default App;

The problem now is that when I log the movieData inside the Movies.jsx file its value is undefined. Even though, when I log it inside the MovieContextProvider.jsx it appears as expected.

So, do I’m using useContext(context) in a wrong way? I have done many research online and I have found some articles here on Stack Overflow, but I have failed to solve the problem.

Any help would be greatly appreciated.

2

Answers


  1. It looks like you forgot to export the MovieContext itself from the MovieContextProvider.jsx file. You’ll need to export this so that you can import and use it in the Movies.jsx file.

    Modify the MovieContextProvider.jsx file to include an export for MovieContext:

    // other imports...
    export const MovieContext = createContext();
    // rest of your code...
    

    Then in your Movies.jsx, you’ll want to modify the import statement to import it from the correct file:

    import { MovieContext } from '../Contexts/MovieContextProvider';
    

    Now, the context should be available in the Movies component, and you should be able to access the movieData as expected.

    Also, be aware that since the movieData is fetched asynchronously, it will initially be undefined until the data is fetched and populated into the context. You may want to include a loading state or conditional rendering to handle this. You can adjust the Movies component to handle this scenario:

    function Movies() {
        const movieData = useContext(MovieContext);
    
        if (!movieData) {
            return <div>Loading movies...</div>;
        }
    
        // rest of your code...
    }
    

    This way, the component will render a loading message until the movieData is available.

    Login or Signup to reply.
  2. Use react hook like this.

    Add hook function to MovieContextProvider.jsx

    export const useMovieContext = () => useContext(MovieContext)
    

    Then, use useMovieContext function instead of useContext(MovieContext) in Movies.jsx

    const movieData = useMovieContext()
    
    useEffect(() => {
        console.log(movieData);
    }, [movieData])
    

    Finally, you can get axios result in Movies.jsx

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search