Get single data from state in React

Viewed 162

I'm trying to make a page to show the details of each video.
I fetched multiple video data from the back-end and stored them as global state. This code works if I go to the page through the link inside the app. But If I reload or open the URL directory from the browser, It can not load the single video data.

How should I do to make this work?

Thanx

Single Video Page

import { useState, useEffect, useContext } from "react";
import { useParams } from "react-router-dom";
import { VideoContext } from "../context/videoContext";

const SingleVideo = () => {
  let { slug } = useParams();

  const [videos, setVideos] = useContext(VideoContext);
  const [video, setVideo] = useState([]);

  useEffect(() => {
    const result = videos.find((videos) => {
      return videos.uuid === slug;
    });
    setVideo((video) => result);
  }, []);

  return (
    <>
      <div>
        <h1>{video.title}</h1>
        <p>{video.content}</p>
        <img src={video.thumbnail} alt="" />
      </div>
    </>
  );
};
export default SingleVideo;

Context

import React, { useState, createContext, useEffect } from "react";
import Axios from "axios";
import { AxiosResponse } from "axios";

export const VideoContext = createContext();

export const VideoProvider = (props) => {
  const [videos, setVideos] = useState([]);

  const config = {
    headers: { "Access-Control-Allow-Origin": "*" },
  };
  useEffect(() => {
    //Fetch Vidoes
    Axios.get(`http://localhost:5000/videos`, config)
      .then((res: AxiosResponse) => {
        setVideos(res.data);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  return (
    <VideoContext.Provider value={[videos, setVideos]}>
      {props.children}
    </VideoContext.Provider>
  );
};
1 Answers

I think the reason is because when you refresh the app, you fetch the video data on context and the useEffect on your single video page component runs before you receive those data.

To fix you can simply modify slightly your useEffect in your single video component to update whenever you receive those data:

useEffect(() => {
  if (videos.length) {
    const result = videos.find((videos) => {
      return videos.uuid === slug;
    });
    setVideo((video) => result);
  }
}, [videos]);
Related