NextJS how to fetch data after click event?

Viewed 10727

I have problem with load data to component after click on button. I use getInitialProps to first load data on page.

How to load new data and past them to {data} after click?

export default function Users({ data }) {
  const fetchData = async () => {
    const req = await fetch("https://randomuser.me/api/?gender=male&results=100");
    const data = await req.json();

    return { data: data.results };
  };
  const handleClick = (event) => {
    event.preventDefault();

    fetchData();
  };
  return (
    <Layout>
      <button onClick={handleClick}>FETCH DATA</button>
      {data.map((user) => {
        return (
          <div>
            {user.email}
            <img src={user.picture.medium} alt="" />
          </div>
        );
      })}
    </Layout>
  );
}

Users.getInitialProps = async () => {
  const req = await fetch(
    "https://randomuser.me/api/?gender=female&results=10"
  );
  const data = await req.json();
  return { data: data.results };
};

Thank a lot for help!

3 Answers

Use useState with the default value being the data you initially retrieved via getInitialProps:

import { useState } from 'React';

export default function Users({ initialData }) {
    const [data, setData] = useState(initialData);

    const fetchData = async () => {
        const req = await fetch('https://randomuser.me/api/?gender=male&results=100');
        const newData = await req.json();

        return setData(newData.results);
    };

    const handleClick = (event) => {
        event.preventDefault();
        fetchData();
    };

    return (
        <Layout>
            <button onClick={handleClick}>FETCH DATA</button>
            {data.map((user) => {
                return (
                    <div>
                        {user.email}
                        <img src={user.picture.medium} alt="" />
                    </div>
                );
            })}
        </Layout>
    );
}

Users.getInitialProps = async () => {
    const req = await fetch('https://randomuser.me/api/?gender=female&results=10');
    const data = await req.json();
    return { initialData: data.results };
};

Sidenote: Times have changed and it would seem that user1665355 is indeed correct:

Recommended: getStaticProps or getServerSideProps

If you're using Next.js 9.3 or newer, we recommend that you use getStaticProps or getServerSideProps instead of getInitialProps.

These new data fetching methods allow you to have a granular choice between static generation and server-side rendering.

import { useState } from 'React';

export default function Users({ initialData }) {
  const [data, setData] = useState(initialData);

  const fetchData = async () => {
    const req = await fetch('https://randomuser.me/api/?gender=male&results=100');
    const newData = await req.json();

    setData(newData.results);
  };

  const handleClick = (event) => {
    event.preventDefault();
    fetchData();
  };

  return (
    <Layout>
      <button onClick={handleClick}>FETCH DATA</button>
      {data.map(user => {
        return (
          <div key={user.login.uuid}>
            {user.email}
            <img src={user.picture.medium} alt="" />
          </div>
        );
      })}
    </Layout>
  );
}

Users.getInitialProps = async () => {
  const req = await fetch('https://randomuser.me/api/?gender=female&results=10');
  const data = await req.json();
  
  return { initialData: data.results };
};

I would like to list my notes about George's code. At least, it should pay attention to them.

First of all, it should attach any key to a div element otherwise a warning will have appeared in the browser console. Here is an article about using keys: https://reactjs.org/docs/lists-and-keys.html#keys

As well, the keyword return can be removed from the fetchData function that doesn't return a response.

Related