Api calling with redux is getting delayed

Viewed 36

**In useEffect hook i am trying to make small description of movie around 120 words. task in useEffect are in such manner **

  1. calling api through redux
  2. checking if there is movie and movie.overview
  3. then making small description from the overview got from api

but the useState view is not reflecting on time, as if i choose movie black widow it shows me default view i.e('lorem .....'), and then if i choose another movie from template it will show me the description of last movie black widow

import React, { useEffect, useState } from "react";
import "./MovieTemplate.css";
import Play from "@material-ui/icons/PlayArrow";
import Add from "@material-ui/icons/Add";
import Share from "@material-ui/icons/Share";
import { useParams } from "react-router-dom";
import { connect } from "react-redux";
import { fetchMovie } from "../../redux/actions/postActions";

const IMG_URL = "https://image.tmdb.org/t/p/original/";

function MovieTemplate({ fetchMovie, movie }) {
  const { id } = useParams();

  const desc = [];

  const [view, setView] = useState(
    "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem 
        Ipsum has been the industry standard dummy"
  );

  useEffect(() => {
    const load = async () => {
      await fetchMovie(id);
    };
    load();
    console.log("id ", id);
    console.log("img ", `${IMG_URL}${movie.backdrop_path}`);
    if (movie && movie.overview) {
      for (let i = 0; i < 124; i++) {
        desc.push(movie.overview[i]);
      }
      const a = desc.join("");
      setView(a);
      console.log("desc ", desc.join(""));
    }
  }, []);

  return (
    <div className="movieTemplate">
      <div className="movieTemplate-main">
        <div className="movieTemplate-body">
          <div className="movieTemplate-content">
            <div className="movieTemplate-content-inside">
              <p className="movieTemplate-content-badge">VIP</p>
              <p className="movieTemplate-content-title">
                {movie.title ? movie.title : "Black Panther"}
              </p>
              <p className="movieTemplate-content-time">
                1 hr 33 min . 2021 . Musical . 15+ . Hindi
              </p>
              <p className="movieTemplate-content-description">
                {movie.overview
                  ? `${view}...`
                  : "Lorem Ipsum is simply dummy text of the printing and typesetting 
                industry. Lorem Ipsum has been the industry standard dummy"}
              </p>
              <div className="movieTemplate-content-player">
                <span className="movieTemplate-watch">
                  <Play
                    style={{ fontSize: 30, color: "#fff" }}
                    className="movieTemplate-play-icon"
                  />
                  <p className="movieTemplate-watch-movie">Watch Movie</p>
                </span>
                <div className="movieTemplate-share-watch">
                  <span className="movieTemplate-watch-list">
                    <Add
                      style={{ fontSize: 30, color: "#fff" }}
                      className="movieTemplate-add-icon"
                    />
                    <p className="movieTemplate-add-movie">WATCHLIST</p>
                  </span>
                  <span className="movieTemplate-share">
                    <Share
                      style={{ fontSize: 30, color: "#fff" }}
                      className="movieTemplate-share-icon"
                    />
                    <p className="movieTemplate-share-movie">SHARE</p>
                  </span>
                </div>
              </div>
            </div>
          </div>
          <img
            src={
              movie.backdrop_path
                ? `${IMG_URL}${movie.backdrop_path}`
                : "https://cdn.guidingtech.com/media/assets/_1200x630_crop_center- 
                   center_82_none/Black-Panther-Movie-Wallpapers.jpg?mtime=1516263479"
            }
            alt=""
            className="movieTemplate-img"
          />
        </div>
      </div>
      <span className="movieTemplate-tablet-watch">
        <Play
          style={{ fontSize: 30, color: "#fff" }}
          className="movieTemplate-tablet-play-icon"
        />
        <p className="movieTemplate-tablet-watch-movie">Watch Movie</p>
      </span>
    </div>
  );
}

const mapStateTOProps = (state) => ({
  movie: state.posts.movie,
});

export default connect(mapStateTOProps, { fetchMovie })(MovieTemplate);

redux

import { FETCH_TREND_MOVIE, FETCH_TREND_SERIES, FETCH_MOVIE, GET_MOVIE_ID } from "./types";
import {api} from "../Api"; 
import { fetch_movie, fetch_trend_movie, fetch_trend_series } from '../../services/URL';

export const fetchTrendMovie = () => async (dispatch) => {
  const response = await api("GET", fetch_trend_movie, {api_key:"09a103acc6695c0ecde189600656e038", language: "en-US"})
  response.data.results.length = 20
  console.log("response 1", response.data.results)
  return dispatch({ type:FETCH_TREND_MOVIE, payload:response.data.results })
}


export const fetchTrendSeries = () => async (dispatch) => {
  const response = await api("GET", fetch_trend_series, {api_key:"09a103acc6695c0ecde189600656e038", language: "en-US"})
  response.data.results.length = 20
  console.log("response 2", response.data.results)
  return dispatch({ type:FETCH_TREND_SERIES, payload:response.data.results })
}


export const fetchMovie = (id) => async (dispatch) => {
  const response = await api("GET", `${fetch_movie}${id}`, {api_key:"09a103acc6695c0ecde189600656e038", language: "en-US"})
  console.log("response 3", response)
  return dispatch({ type:FETCH_MOVIE, payload:response.data })
}

api through axios

import axios from 'axios';
import { BASE_URL } from '../services/URL';

export const api = async (method, apiUrl, parameter) => {
    var options = {
        method: method,
        url: BASE_URL+apiUrl,
        params: parameter,
      };

      const response = await axios.request(options)
      return response;
}
1 Answers

You should pass id as second argument to useEffect so whenever it changes, effect is invoked.

useEffect(() => {
    const load = async () => {
      await fetchMovie(id);
    };
    load();
    console.log("id ", id);
    console.log("img ", `${IMG_URL}${movie.backdrop_path}`);
    if (movie && movie.overview) {
      for (let i = 0; i < 124; i++) {
        desc.push(movie.overview[i]);
      }
      const a = desc.join("");
      setView(a);
      console.log("desc ", desc.join(""));
    }
  }, [id]);
Related