Reputation: 223
I'm new to hooks and I have this project (https://thereacttimes.netlify.app/
) and it uses the New York Times API to display stories from different news sections.
I created a masthead of section titles. If you click "arts" it will change the URL to https://thereacttimes.netlify.app/arts
but I need to use that section title as the fetch URL param and I'm not sure how to re-render/re-fetch with my useEffect Hook. The fetch URL allows us to pass the section
like this to fetch different stories: fetch("https://api.nytimes.com/svc/topstories/v2/{section}.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr)
.
If you're asking yourself why its working in production now, its because I hard-coded the URL to work as: fetch("https://api.nytimes.com/svc/topstories/v2/home.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr)
What do I change in my useEffect hook? What do I add to the buttons in my masthead component to call the re-render?
News Component
export default function News() {
const [error, setError] = useState(null);
const [stories, setStory] = useState(null);
useEffect(() => {
fetch(`"https://api.nytimes.com/svc/topstories/v2/{section}.json?api-key=""`)
.then((res) => res.json())
.then((data) => {
setTimeout(() => setStory(data), 1500);
console.log("Success ", data);
})
.catch((error) => {
console.log("Error", error);
});
}, []);
if (error) {
return <div>Error: {error.message}</div>;
} else if (!stories) {
return <LoadingBar type={"cylon"} color={"#193152"} />;
} else {
return (
<>
<ul className="stories">
{stories.results.map((story) => {
return (
<Story
title={story.title}
abstract={story.abstract}
img={story.multimedia[0].url}
alt={story.multimedia[0].caption}
link={story.url}
/>
);
})}
</ul>
<Spacer height={100} />
</>
);
}
}
Masthead Component
import React from "react";
import uuid from "uuid";
var sections = [
"arts",
"business",
"fashion",
"health",
"movies",
"opinion",
"politics",
"science",
"sports",
"technology",
];
export default function Masthead() {
return (
<div className="masthead">
{sections.map((section) => {
return (
<a href={section} key={uuid}>
<span>{section}</span>
</a>
);
})}
</div>
);
}
Upvotes: 2
Views: 2914
Reputation: 17888
To be able to rerender the News component when the section changes, you need to add section to the dependency list in the useeffect like [section].
By the way there is no section variable in the News component, I guess what you are trying to do is pass a section parameter to the News component, if so you had better to use routing, and pass the section parameter to the News component.
Here is a working codesandbox with some other changes and refactoring:
Upvotes: 3
Reputation: 7915
I would need to understand the larger context of your app of course to come up with a more elegant solution, but just a cursory look at what you have provided suggests using something as simple as this:
const getCurrentPage = () => {
const url = new URL(window.location.href);
const page = url.pathname.split('/').pop();
return page ? page: 'home';
}
export default function News() {
const [error, setError] = useState(null);
const [stories, setStory] = useState(null);
useEffect(() => {
const section = getCurrentPage();
fetch(`https://api.nytimes.com/svc/topstories/v2/${section}.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr`)
.then((res) => res.json())
.then((data) => {
setTimeout(() => setStory(data), 1500);
console.log("Success ", data);
})
.catch((error) => {
console.log("Error", error);
});
}, []);
...
...
Nice touch on The React Times by the way.
Upvotes: 2