albert_anthony6
albert_anthony6

Reputation: 614

Rendering component with property coming from fetch in componentDidMount React

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.

Upvotes: 0

Views: 318

Answers (1)

Zunaib Imtiaz
Zunaib Imtiaz

Reputation: 3119

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>
        );
    }

Upvotes: 1

Related Questions