1

I am just working through my first React tutorial using hooks - I am using trying to fetch local data within useEffect and then update the state using useState. I am then passing the state into a Context.provider which a child element (Card.js) subscribes to. Even though useEffect runs, the Card component and the state isn't being rerendered/updated. What am I doing wrong?

MainContext.js -

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


import List from '../containers/List';

export const myContext= createContext();


export const MainContext = ({children}) => {

  const [films, setFilms] = useState([]);

  const loadData = () => {
    try {
      fetch('../src/assets/data.json').then( result => result.json()).then(movies => { 
      setFilms(films)      
      }) 
    } catch (error) {
      console.log('there has been an error')
    }}


  useEffect(() => { 

    loadData() 

    },[]);


   return (

      <myContext.Provider value={{films,setFilms }}>
        {children()}
      </myContext.Provider>
    );

  } 

Card.js -

function Card() {

  const {films} = useContext(myContext)

  if (films !== undefined) { 
    return (

      <div>
        { films.map((movie,i) => {
          return (
          <div key={i}>
            <img src={movie.img.src} className='card-img-top' alt={movie.img.alt} />
          <div className='card-body'>
            <h2 className='card-title'>{`#${movie.ranking} - ${movie.title} (${movie.year})`}</h2>
          </div>
          <ul className='list-group list-group-flush'>
            <li className='list-group-item'>{`Distributor: ${movie.distributor}`}</li>
            <li className='list-group-item'>{`Amount: ${movie.amount}`}</li>
          </ul></div>
          )
        })

        }
      </div>
    )
  } else {
  return <div>{'Update Failed'}</div>
  }

}

export default Card

1 Answer 1

1

You don't have any dependency in your useEffect array. This is why it doesn't trigger again once the app is mounted. You need to pass it a dependency, so it can run again each time the dependency value changes. Also, consider adding async before your loadData function.

Sign up to request clarification or add additional context in comments.

2 Comments

Thankyou - I tried adding the films variable to the dependancy array but that didnt fix it. Seems the issue is that the state in useContext isnt updating - when I go into developer tools and inspect the Card component the films variable is still set to an empty array.... any ideas?
Found the issue - I had a typo and was setting the state to the old state not the fetched data under movies! Cheers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.