0

Good day,

While learning Java Script I faced the challenge with showing news details from World News API. After clicking the Link in order to move to NewsDetails page, the hash changes, therefore NewsDetails page shows mismatched text.

Could you please advise how to deal with it? Below is my SliderNewsLine component:

import { WN_API_KEY, WN_API, NEWS_CACHE_TIME} from "../env";
import { useState, useEffect, useRef } from "react";
import NewIt from "./NewIt";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import ky from "ky";
import { toast } from "react-toastify";

function SliderNewsLine() {
  const isDev = false; 

  const [newsLine, setNewsLine] = useState([]);
  
  const fetchCount = useRef(0);

  async function fetchNews(){
    if(fetchCount.current !== 0)
      return false;

    fetchCount.current++;
    const storageNews = localStorage.getItem('newsLine');
    const lastUpdate = +localStorage.getItem('LastNewsUpdate');
    if(storageNews !== null){
      const now = new Date().getTime();
      if((now - lastUpdate) < NEWS_CACHE_TIME) {
        setNewsLine(JSON.parse(storageNews));
        return false;
      } 
    }
    try {
      const url = isDev 
      ? './mock/mockNews.json'
      : `${WN_API}search-news?api-key=${WN_API_KEY}&text=design&language=en&number=6`;
      const resp = await ky(url, {
          timeout: 15000,
        }).json();
        
      setNewsLine(resp.news);
      localStorage.setItem('newsLine', JSON.stringify(resp.news));
      localStorage.setItem('lastNewsUpdate', new Date().getTime());
    } catch (err){
      console.log(err);
      toast.error("Some error occured");
    }
  }

  useEffect(() => {
    fetchNews();
  }, []);

  [...]

  return (
    <div className="news-slider">
      <div className="newSlider">
        <Slider {...sliderFirstSet} ref={sliderNewRef}>
          {newsLine.map(item =>  (
            <NewIt respData={item} key={item.id} />
          ))}
        </Slider>
      </div>
    </div>
  )
}
export default SliderNewsLine;

         

Below is my NewIt component:

import { Link } from "react-router-dom";
import formatDate from "../helpers/formatDate"
import newsDefaultImg from '../assets/images/newsDefault.jpg';

function NewIt({respData, randomIt}) {

  const hash = btoa(respData.url);

  return (
    <>
      <div className="content-wrap-first">
        <Link to={`/news/${hash}`} className="new-topic" title="Go to news details">{respData.title}</Link>
      </div>
      <div className="content-wrap2">
        <div className="date-news">{formatDate(respData.publish_date)}</div>
      </div>
      <div className="img-wrap-new">
        <img src={respData.image ?? newsDefaultImg} alt={respData.title} />
      </div>
    </>
  )
}
export default NewIt;

Here is my NewsDetail component:

import { WN_API, WN_API_KEY } from "../env";
import { useParams } from "react-router-dom";
import { useState, useRef, useEffect } from "react";
import newsDefaultImg from '../assets/images/newsDefault.jpg';
import Loader from "../components/Loader";
import ky from "ky";
import '../assets/scss/news-details.scss'



function NewsDetails(){
  const { hash } = useParams();
  const [news, setNewsData] = useState({});
  const fetchCount = useRef(0);

  async function fetchOneNews(){
    if(fetchCount.current !== 0){
      return false;
    }
    fetchCount.current++;

    const storageNews = localStorage.getItem(hash);
    if(storageNews !== null){
      setNewsData(JSON.parse(storageNews));
      return false;
    }
    
    try {
      const url = atob(hash);
      const resp = await ky(`${WN_API}extract-news?api-key=${WN_API_KEY}&url=${url}`).json();
      setNewsData(resp);
      localStorage.setItem(hash, JSON.stringify(resp)); 
    } catch (err){
      console.log(err);
      toast.error("error");
    }
  }

  useEffect(() => {
    fetchOneNews();
  }, []);



  return(
    <div id="news-details-page">
      <section id="detail-text-sec">
        <div className="container">
          <div className="detail-text-wrap">
            <div className="text-col">
              <div className="poster-detail-wrap">
                <img src={news.image ? news.image : newsDefaultImg}  />
              </div>
              <p>{news.text}</p>
            </div>
          </div>
        </div>
      </section>
    </div>
  )
}
export default NewsDetails;

Mizuki
  • 1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Aug 23 '23 at 22:44

1 Answers1

0

Hello i know how to fix this. Apply the useEffect hook in the NewsDetails component to listen for hash changes

 useEffect(() => {
    fetchOneNews();
  }, [hash]);