I have written a Reactjs code . Here the first api is rendering the list of job ids . and in next api each job id is rendering the job detail of that id . here is the example .
api 1 - https://hacker-news.firebaseio.com/v0/jobstories.json
o/p 1 - [35908337, 35904973, 35900922, 35893439, 35890114, 35880345, ...]
api 2 - https://hacker-news.firebaseio.com/v0/item/35908337.json
o/p 2 - {
"by": "jamilbk",
"id": 35908337,
"score": 1,
"time": 1683838872,
"title": "Firezone (YC W22) is hiring Elixir and Rust engineers",
"type": "job",
"url": "https://www.ycombinator.com/companies/firezone/jobs"
}
Now I have wriiten a react js code for it to achieve the same .
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [jobId, setJobId] = useState([]);
const [jobData, setJobData] = useState([]);
const [pages, SetPages] = useState(0);
const [hasMore, setHasMore] = useState(true);
const [loading, setLoading] = useState(false);
const No_Of_Pages = 6;
useEffect(() => {
fetchJobId();
}, []);
useEffect(() => {
if (jobId.length > 0) fetchJobData();
}, [pages, jobId]);
const fetchJobId = async () => {
const response = await fetch(
"https://hacker-news.firebaseio.com/v0/jobstories.json"
);
const data = await response.json();
setJobId(data);
};
const fetchJobData = async () => {
setLoading(true);
const JobrangeId = jobId.slice(
pages * No_Of_Pages,
(pages + 1) * No_Of_Pages
); // 0-6 , 6-12 , 12-18 ...
const JobDataPromise = JobrangeId.map(async (id) => {
const response = await fetch(
`https://hacker-news.firebaseio.com/v0/item/${id}.json`
);
const data = await response.json();
return data;
});
const jobInfo = await Promise.all(JobDataPromise);
setJobData((prevjob) => [...prevjob, ...jobInfo]);
setHasMore((pages + 1) * No_Of_Pages < jobData.length);
setLoading(false);
};
return (
<div className="">
<div className="h-[500px] w-[100%] relative p-4 bg-gray-50 overflow-y-scroll">
<div className="flex flex-col w-[100%] h-[100%] items-center ">
<p className="text-orange-400 font-bold text-2xl">
{" "}
Hacker News Jobs Board
</p>
{jobData.length > 0
? jobData.map((ele, index) => (
<div
className="w-5/6 h-16 border-[1.5px] border-gray-300 m-3 p-1.5 bg-white"
key={index}
>
<div className="flex flex-col ">
<div>
<p className="font-bold text-black text-xl">
{ele?.title}
</p>
</div>
<div className="flex justify-start gap-2">
<p className="font-normal text-base">By {ele?.by}</p>
<p>-</p>
<p>{ele?.time}</p>
</div>
</div>
</div>
))
: null}
<div className="w-5/6 flex justify-start">
<button
className="p-3 bg-orange-400 text-white rounded-md"
onClick={() => SetPages(pages + 1)}
disabled={hasMore}
>
{loading ? "Loading..." : "Load more"}
</button>
</div>
</div>
</div>
</div>
);
}
export default App;
The error I am getting here is on intial render it is rendering 12 job details instead of 6 . In 12 the last 6 are the same to that of first 6 . in subsequent rendering on click of load more button it is rendering correctly . Why it is happening like that ? What is wrong in my code ? Thanks in advance .