Back

Technologies:

javascriptjavascript
reactjsreactjs
avatar
Tolerim
24 days ago

Is it possible to modify the fetch URL for getServerSideProps through onClick?

I am having trouble finding a solution for changing the fetch URL in my code. Specifically, I need to modify the let page variable and then refresh getServerSideProps so that all news articles can be re-rendered by clicking a button. Is there a way to accomplish this, or do I need to find an alternative method?

import Head from "next/head";
import { NewsArticle, NewsResponse } from "@/modules/NewsArticles";
import { GetServerSideProps } from "next";
import NewsArticleGrid from "@/components/NewsArticleGrid";
import { Button } from "react-bootstrap";
import { useRouter } from "next/router";

interface BreakingNewsPageProps {
  newsArticles: NewsArticle[];
}

let page =
  "https://newsapi.org/v2/everything?q=apple&from=2023-05-03&to=2023-05-03&sortBy=popularity&apiKey=";

export const getServerSideProps: GetServerSideProps<BreakingNewsPageProps> = async () => {
  const response = await fetch(page + process.env.NEWSAPIKEY);
  const newsResponse: NewsResponse = await response.json();
  return {
    props: { newsArticles: newsResponse.articles },
  };
};

export default function BreakingNewsPage({ newsArticles }: BreakingNewsPageProps) {
  const router = useRouter();

  return (
    <>
      <Head>
        <title>Breaking news </title>
      </Head>
      <main>
        <h1>Breaking News</h1>
        <Button
          onClick={() => {
            page =
              "https://newsapi.org/v2/everything?q=tesla&from=2023-04-03&sortBy=publishedAt&apiKey=";
            console.log(page);
            router.push(router.asPath);
          }}
        >
          Change URL
        </Button>
        <NewsArticleGrid articles={newsArticles} />
      </main>
    </>
  );
}
Answers(2)
avatar
Vogi
23 days ago
Verified Answer
You can modify the page variable by using the useState hook to store the URL and then update it when the button is clicked. Here's an example:
import Head from "next/head";
import { NewsArticle, NewsResponse } from "@/modules/NewsArticles";
import { GetServerSideProps } from "next";
import NewsArticleGrid from "@/components/NewsArticleGrid";
import { Button } from "react-bootstrap";
import { useRouter } from "next/router";
import { useState } from "react";

interface BreakingNewsPageProps {
  newsArticles: NewsArticle[];
}

export const getServerSideProps: GetServerSideProps<BreakingNewsPageProps> = async () => {
  const response = await fetch(page + process.env.NEWS_API_KEY);
  const newsResponse: NewsResponse = await response.json();
  return {
    props: { newsArticles: newsResponse.articles },
  };
};

export default function BreakingNewsPage({ newsArticles }: BreakingNewsPageProps) {
  const router = useRouter();
  const [page, setPage] = useState(
    "https://newsapi.org/v2/everything?q=apple&from=2023-05-03&to=2023-05-03&sortBy=popularity&apiKey="
  );

  return (
    <>
      <Head>
        <title>Breaking news </title>
      </Head>
      <main>
        <h1>Breaking News</h1>
        <Button
          onClick={() => {
            setPage(
              "https://newsapi.org/v2/everything?q=tesla&from=2023-04-03&sortBy=publishedAt&apiKey="
            );
            console.log(page);
            router.push(router.asPath);
          }}
        >
          Change URL
        </Button>
        <NewsArticleGrid articles={newsArticles} />
      </main>
    </>
  );
}
This way, you can modify the page variable and refresh getServerSideProps so that all news articles can be re-rendered by clicking a button.

Sources

Data Fetching: getServerSideProps | Next.jsUsing getServerSideProps inside a component · vercel next.js ...Next.js: Using getServerSideProps() with TypeScriptgetServerSideProps() in Next.js - backbencher.devjavascript - In NextJs how to change getServerSideProps with change ...
avatar
Tolerim
24 days ago
To change the fetch url and refresh getServerSideProps, you will need to use a different approach. Since getServerSideProps is executed on the server and not on the client, changing page and calling router.push will not refresh the data from the server. One alternative way to achieve your desired result is to use useEffect hook in your functional component where you can update the fetch url based on a state value that you can change when you click the button. Here is an example of how you can achieve this:
import Head from "next/head";
import { NewsArticle, NewsResponse } from "@/modules/NewsArticles";
import { GetServerSideProps } from "next";
import NewsArticleGrid from "@/components/NewsArticleGrid";
import { Button } from "react-bootstrap";
import { useRouter } from "next/router";
import { useState, useEffect } from "react";

interface BreakingNewsPageProps {
  newsArticles: NewsArticle[];
}

export const getServerSideProps: GetServerSideProps<BreakingNewsPageProps> = async () => {
  const page = "https://newsapi.org/v2/everything?q=apple&from=2023-05-03&to=2023-05-03&sortBy=popularity&apiKey=" + process.env.NEWS_API_KEY;
  const response = await fetch(page);
  const newsResponse: NewsResponse = await response.json();
  return {
    props: { newsArticles: newsResponse.articles },
  };
};

export default function BreakingNewsPage({ newsArticles }: BreakingNewsPageProps) {
  const router = useRouter();
  const [pageUrl, setPageUrl] = useState(page); // Set the initial fetch url

  useEffect(() => {
    // Call fetch with updated url when pageUrl changes
    const fetchNewsArticles = async () => {
      const response = await fetch(pageUrl);
      const newsResponse: NewsResponse = await response.json();
      setNewsArticles(newsResponse.articles);
    };
    fetchNewsArticles();
  }, [pageUrl]);

  const handleButtonClick = () => {
    const newPageUrl = "https://newsapi.org/v2/everything?q=tesla&from=2023-04-03&sortBy=publishedAt&apiKey=" + process.env.NEWS_API_KEY;
    setPageUrl(newPageUrl);
  };

  return (
    <>
      <Head>
        <title>Breaking news</title>
      </Head>
      <main>
        <h1>Breaking News</h1>
        <Button onClick={handleButtonClick}>Change url</Button>
        <NewsArticleGrid articles={newsArticles} />
      </main>
    </>
  );
}
In this example, we use useState to set the initial fetch url for pageUrl. We also use useEffect with a dependency on pageUrl to call fetch with the updated url when pageUrl changes. Finally, we update pageUrl when the button is clicked, which triggers a re-render of the component and calls fetch with the updated url.
;