0

I am trying to render a component that needs props passed to it. These props require data that can only come from an api fetch. The issue is that I'm fetching from the api in componentDidMount but the render method gets mounted before the componentDidMount method so it says that it cannot read property of undefined because it tries to render the component before the data gets to be fetched. heroImage is an object that gets stored into the state during the fetch call but it does not exist in the state before the fetch call.

class Home extends React.Component{
    constructor(){
        super();
        this.state={
            searchTerm: '',
            movies: [],
            error: false,
            loading: false,
        };
    }

    componentDidMount(){
        const fetchMovies = async endpoint => {

            const isLoadMore = endpoint.search('page');
            try{
                const result = await (await fetch(endpoint)).json();
                this.setState(prev => ({
                    ...prev,
                    movies: isLoadMore !== -1 ? [...prev.movies, ...result.results] : [...result.results],
                    heroImage: prev.heroImage || result.results[0],
                    currentPage: result.page,
                    totalPages: result.total_pages
                }));
            } catch(error){
                alert(error);
            }
        }
        console.log('...fetching');
        fetchMovies(POPULAR_BASE_URL);
        console.log('done fetching...');
    }

    render(){
        const {heroImage} = this.state;
        return(
            <React.Fragment>
                <HeroImage
                    image={`${IMAGE_BASE_URL}${BACKDROP_SIZE}${heroImage.backdrop_path}`}
                    title={heroImage.original_title}
                    text={heroImage.overview}
                />
            </React.Fragment>
        );
    }
};

The app has trouble reading the image prop that's getting passed to the HeroImage component. This is because it requires the heroImage object that only comes from the fetch call to exist so that it can select the backdrop_path property from it. Since render method mounts first, the object is never stored in the state. This is the issue I need help solving. Thanks.

1 Answer 1

1

Just add an iternary check like this. So it only renders when there is data in heroImage

   render(){
        const {heroImage} = this.state;
        return(
            <React.Fragment>
                heroImage && <HeroImage
                    image={`${IMAGE_BASE_URL}${BACKDROP_SIZE}${heroImage.backdrop_path}`}
                    title={heroImage.original_title}
                    text={heroImage.overview}
                />
            </React.Fragment>
        );
    }
Sign up to request clarification or add additional context in comments.

2 Comments

This worked, thank you. So the && only returns the first falsy value correct? I'm still trying to understand how it works. I'll mark this as the answer when I'm allowed to. It says it's still too early to accept any answers.
It checks whether both of these are true, The Component will always return true because it is going to render without any problem. The && just makes sure that there is something is heroImage first. So when it is true the Component has the data rather than something undefined.

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.