Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is ReactJS not reflecting changes in array to my UI?

import React, { useState } from "react";

export default function Recommend() {
  const [animeName, setAnimeName] = useState("");
  const [anilistURL, setanilistURL] = useState("");
  const [errorMsg, setErrorMsg] = useState("");
  const [loading, setLoading] = useState(false);
  const [loadingReviews, setLoadingReviews] = useState(false);
  const [reviewTitles, setreviewTitles] = useState([]);

  const handleSubmit = async () => {
    try {
      setLoading(true);
      setreviewTitles([]);
      setanilistURL("");
      setErrorMsg("");

      const response = await fetch("http://localhost:8000/get-anilist-url", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          anime_title: animeName,
        }),
      });
      if (!response.ok) {
        const errorData = await response.json();
        setErrorMsg(errorData.error || "Unable to get response");
      }
      const data = await response.json();
      setanilistURL(data.anilist_url || "No URL found");
      setErrorMsg("");
    } catch (error) {
      setErrorMsg("An error occurred: " + error.message);
    } finally {
      setLoading(false);
      getReviews();
    }
  };

  const getReviews = async () => {
    try {
      setLoadingReviews(true);
      setErrorMsg("");
      const anilistReviewsURL = anilistURL + "/reviews";
      const response = await fetch(
        "http://localhost:3000/api/v1/scrape/get-review-titles",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ reviewsLink: anilistReviewsURL }),
        }
      );
      const data = await response.json();
      if (!response.ok) {
        setErrorMsg(data.error || "Unable to get response");
      }
      setreviewTitles((prevTitles) => [
        ...prevTitles,
        data.reviewTitles
      ]);
      setErrorMsg("");

    } catch (error) {
      setErrorMsg("An error occurred: " + error);
    }
    finally {
      setLoadingReviews(false);
    }
  };

  return (
    <div className="flex flex-col h-screen bg-slate-700">
      <div className="flex-grow bg-slate-600 p-5 font-mono">
        {loading && <div className="text-white">Loading...</div>}
        {errorMsg && <div className="text-red-500">{errorMsg}</div>}
        {anilistURL && (
          <div className="text-yellow-100">
            <p>Anilist URL:</p>
            <a href={anilistURL} target="_blank" rel="noopener noreferrer">
              {anilistURL}
            </a>
          </div>
        )}
        {loadingReviews && <div className="text-white">Loading...</div>}
        {reviewTitles && (
          reviewTitles.map((reviewTitle) => {
            (
              <div className = "text-yellow-500 pt-3">
                {reviewTitle}
              </div>
            )
          })
        )}
      </div>
      <div className="p-4 flex items-center justify-between bg-slate-800">
        <h3 className="text-gray-500 text-3xl font-mono">
          Enter anime to be analyzed
        </h3>
        <textarea
          type="text"
          className="bg-slate-700 font-mono text-white text-2xl p-3 border-none outline-none w-full rounded-full"
          placeholder="Enter your prompt..."
          value={animeName}
          onChange={(e) => setAnimeName(e.target.value)}
        />
        <button
          className="bg-slate-700 font-mono text-white text-2xl p-4 rounded-full hover:bg-slate-600 transition duration-200 ml-5"
          onClick={handleSubmit}
        >
          Analyze
        </button>
      </div>
    </div>
  );
}

This is my code. My problem is mainly with the review titles. They are not displaying on the UI even though I am setting their state in the getReviews() function. There is nothing wrong with my API endpoints I have tested them with Postman and CORS is also handled. The Anilist URL is being displayed correctly after I set its state in the handleSubmit() function even Loading… from loadingReviews state appears but the first time I click on the analyze button it displays the anilist URL but says failed to fetch status 404 for the review titles and the second time I click analyze it displays the anilist URL as before shows Loading… from the loadingReviews state but doesn’t display anything. From what I have researched it looks like the problem is with the asynchronous nature of useState but I am not really able to understand how to solve this problem. When I console log the reviewTitles it works albeit after clicking the second time(the first time I get a failed to fetch status 404 as I said before) but nothing is displayed on the frontend as I expect. How do I solve this problem? Any help would be appreciated greatly.

I have tried setting reviewTitles using a callback function but that did not work either. Console logging helped me see that there was a problem but I do not understand why nothing displays the first time I click analyze even though I console logged directly after setting the state. I thought of using useEffect() but this does not seem to be the correct usecase for it.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In your case when data is updated there is no event listener for this one . as a example you have updated data but not reflect in your code .
first define state variable then update it
add use effect event listener to listener and update component.

Here’s an updated version of your React component, with a proper state update and an useEffect hook to listen for changes and update the component when necessary:

import React, { useState, useEffect } from "react";

export default function Recommend() {
const [animeName, setAnimeName] = useState("");
const [anilistURL, setAnilistURL] = useState("");
const [errorMsg, setErrorMsg] = useState("");
const [loading, setLoading] = useState(false);
const [loadingReviews, setLoadingReviews] = useState(false);
const [reviewTitles, setReviewTitles] = useState([]);

useEffect(() => {
if (anilistURL) {
getReviews();
}
}, [anilistURL]);

const handleSubmit = async () => {
try {
setLoading(true);
setReviewTitles([]);
setAnilistURL("");
setErrorMsg("");

  const response = await fetch("http://localhost:8000/get-anilist-url", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      anime_title: animeName,
    }),
  });

  if (!response.ok) {
    const errorData = await response.json();
    throw new Error(errorData.error || "Unable to get response");
  }

  const data = await response.json();
  setAnilistURL(data.anilist_url || "No URL found");
} catch (error) {
  setErrorMsg("An error occurred: " + error.message);
} finally {
  setLoading(false);
}

};

const getReviews = async () => {
try {
setLoadingReviews(true);
setErrorMsg("");

  const anilistReviewsURL = `${anilistURL}/reviews`;
  const response = await fetch(
    "http://localhost:3000/api/v1/scrape/get-review-titles",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ reviewsLink: anilistReviewsURL }),
    }
  );

  if (!response.ok) {
    const errorData = await response.json();
    throw new Error(errorData.error || "Unable to get response");
  }

  const data = await response.json();
  setReviewTitles(data.reviewTitles || []);
} catch (error) {
  setErrorMsg("An error occurred: " + error.message);
} finally {
  setLoadingReviews(false);
}

};

return (

{loading && Loading…}
{errorMsg && {errorMsg}}
{anilistURL && (

Anilist URL:

{anilistURL}

)}
{loadingReviews && Loading…}
{reviewTitles.length > 0 && (
reviewTitles.map((reviewTitle, index) => (

{reviewTitle}

))
)}

Enter anime to be analyzed

<textarea
type="text"
className="bg-slate-700 font-mono text-white text-2xl p-3 border-none outline-none w-full rounded-full"
placeholder="Enter your prompt…"
value={animeName}
onChange={(e) => setAnimeName(e.target.value)}
/>

Analyze

);
}

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading