Home > database >  React is rendering before api data arrived
React is rendering before api data arrived

Time:04-25

i have an ojbect inside an object and i want to extract the sub object to map it but the component is readered before the data is arrived

the main object name is Movie and the sub object is Categories

and i want to map Categories but it says undefind.

import Card from '../UI/Card';
import classes from './MovieDetails.module.css';
import MovieCategoris from './MovieCategories';
import ReactPlayerProps from "react-player";

const MovieDetails = (props) => {

    const Movie = props.Movie
    const image = Movie.Image;
    const Categories = Movie.Categories
    const videoSrc = Movie.Video;

    return (
        <Card>
            <div className={classes.VideoPlayer}>
                <ReactPlayerProps
                    controls
                    volume={1}
                    muted={false}
                    width={"100%"}
                    height={"100%"}
                    url={videoSrc}

                />
            </div>
            <div className={classes.DetailsBox}>
                <div className={classes.Details}>
                    <div className={classes.Title}>
                        <img src={image} />
                    </div>
                    <div className={classes.MovDet}>
                        <h3>{Movie.Title}</h3>
                        <ul>
                            <li>Duration: <label>{Movie.Duration}</label></li>
                            <li>Quality: <label>HD 720</label></li>
                            <li>release date: <label>{Movie.Year}</label></li>
                            <li>IMBb: <label>{Movie.Rate}</label></li>
                        </ul>
                        <h5>Categories</h5>
                        {/* <div>
                            <ul className={classes.Cat_li}>
                                {Categories.map((cat) =>
                                    <li>{cat}</li>
                                )}
                            </ul>
                        </div> */}
                    </div>
                    <div className={classes.Desc}>
                        <p> {Movie.Description} </p>
                    </div>
                </div>
            </div>
        </Card>
    )
}
export default MovieDetails;

this is the function that get the api data and forward it with props to the component.

import MovieDetails from "../components/Content/MovieDetails";
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import FetchedMovie from '../Hooks/fetchSingleMovie'

const MovieDetailsPage = () => {
    const [MovieData, setMovieData] = useState([])
    const MovieId = useParams()
    async function Movie(MovieId) {
        const id = MovieId.movie
        const result = await FetchedMovie(id)
        setMovieData(result)
        return result
    }

    useEffect(() => {
        Movie(MovieId)
    }, [])
    return <MovieDetails Movie={MovieData} />
}

export default MovieDetailsPage;

this is the object i have on the api sever

CodePudding user response:

it happens because the api will render after your first moviedetails call; you can use an if before your map that everytime its defined, map the function like this: {categories && categories.map ... }; because everytime that the props changes page will rerender;

CodePudding user response:

That's because you ara passing an empty array in your MovieDetails component in MovieDetailsPage

you can render MovieDetails whene your data is ready

Try to change it in something like this

import MovieDetails from "../components/Content/MovieDetails";
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import FetchedMovie from '../Hooks/fetchSingleMovie'

const MovieDetailsPage = () => {
    const [MovieData, setMovieData] = useState(null)
    const MovieId = useParams()
    async function Movie(MovieId) {
        const id = MovieId.movie
        const result = await FetchedMovie(id)
        setMovieData(result)
        return result
    }

    useEffect(() => {
        Movie(MovieId)
    }, [])
    return MovieData && <MovieDetails Movie={MovieData} />
}

export default MovieDetailsPage;

  • Related