getInitialProps is not sending data to the page component when wanting to fetch initial data and later update it with a button

huangapple go评论106阅读模式
英文:

getInitialProps is not sending data to the page component when wanting to fetch initial data and later update it with a button

问题

我在Next.js v13.4.12中的app\page.tsx组件中有一个按钮。当我点击它时,我希望它调用handleClick函数。

但是getInitialProps函数没有被调用,也没有将props发送给Page组件,我该怎么办?

实际上,我希望当页面首次渲染时,即使我们没有点击按钮,数据也会在页面上呈现。

'使用客户端'
import { useState } from 'React';

export default function Page({ 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}>获取数据</button>
            {data.map((user) => {
                return (
                    <div>
                        {user.email}
                        <img src={user.picture.medium} alt="" />
                    </div>
                );
            })}
        </Layout>
    );
}

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

I have a component at app\page.tsx in Next.js v13.4.12, containing a button. When I click on it, I want it to call the handleClick func.

But the function getInitialProps is not called and doesn't send props to the Page component, what should I do?

In fact, I want when the page render for the first time, even if we are not clicking on the button, data render on the page.

&#39;use client&#39;
import { useState } from &#39;React&#39;;

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

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

        return setData(newData.results);
    };

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

    return (
        &lt;Layout&gt;
            &lt;button onClick={handleClick}&gt;FETCH DATA&lt;/button&gt;
            {data.map((user) =&gt; {
                return (
                    &lt;div&gt;
                        {user.email}
                        &lt;img src={user.picture.medium} alt=&quot;&quot; /&gt;
                    &lt;/div&gt;
                );
            })}
        &lt;/Layout&gt;
    );
}

Page.getInitialProps = async () =&gt; {
    const req = await fetch(&#39;https://randomuser.me/api/?gender=female&amp;results=10&#39;);
    const data = await req.json();
    return { initialData: data.results };
};

答案1

得分: 2

以下是翻译好的部分:

Methods like getServerSideProps and getStaticProps are for fetching data on the server but they only work for page components inside the pages folder (the initial way of setting up routes in Next.js).

自 Next.js 13 版本开始,在 app 目录下,我们有服务器组件 (Server Components),您可以直接在组件体内获取数据,您想要实现的功能如下所示(请注意新增创建的文件):

// app/page.js 🦄;

import Users from "./users";

export default async function Page() {
  const req = await fetch("https://randomuser.me/api/?gender=female&results=10");
  const data = await req.json();

  return <Users initialUsers={data.results} />;
}

您需要添加下面的额外组件,因为您需要客户端交互(这里有一个 onClick 处理程序),而在上面的服务器 Page 组件中无法实现。

// app/users.js 🦄;

"use client";

import { useEffect, useState } from "react";

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

  const handleClick = async (event) => {
    event.preventDefault();
    const req = await fetch("https://randomuser.me/api/?gender=male&results=100");
    const newData = await req.json();
    setData(newData.results);
  };

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

否则,因为您的页面已经是带有 use client 的客户端组件,您可以简单地使用 useEffect 加载初始数据,如下所示:

// app/page.js 🦄;

"use client";

import { useEffect, useState } from "react";

export default function Page() {
  const [data, setData] = useState([]);

  const handleClick = async (event) => {
    event.preventDefault();
    const req = await fetch("https://randomuser.me/api/?gender=male&results=100");
    const newData = await req.json();
    setData(newData.results);
  };

  useEffect(() => {
    fetch("https://randomuser.me/api/?gender=female&results=10")
      .then((res) => res.json())
      .then((data) => {
        setData(data.results);
      });
  }, []);

  return (
    <div>
      <button onClick={handleClick}>FETCH DATA</button>
      {data.map((user, index) => {
        return (
          <div key={index}>
            {user.email}
            <img src={user.picture.medium} alt="" />
          </div>
        );
      })}
    </div>
  );
}
英文:

Methods like getServerSideProps and getStaticProps are for fetching data on the server but they only work for page components inside the pages folder (the initial way of setting up routes in Next.js).

Since Next.js 13, in the app directory, we have Server Components, where you can fetch data directly in the component body, where what you want to achieve would be done as below (notice the additional file created):

// app/page.js &#128072;&#127997;
import Users from &quot;./users&quot;;
export default async function Page() {
const req = await fetch(&quot;https://randomuser.me/api/?gender=female&amp;results=10&quot;);
const data = await req.json();
return &lt;Users initialUsers={data.results} /&gt;;
}

You need the below additional component because you need client interactivities (an onClick handler here), which you cannot have in the server Page component above.

// app/users.js &#128072;&#127997;
&quot;use client&quot;;
import { useEffect, useState } from &quot;react&quot;;
export default function Users({ initialUsers }) {
const [data, setData] = useState(initialUsers);
const handleClick = async (event) =&gt; {
event.preventDefault();
const req = await fetch(&quot;https://randomuser.me/api/?gender=male&amp;results=100&quot;);
const newData = await req.json();
setData(newData.results);
};
return (
&lt;div&gt;
&lt;button onClick={handleClick}&gt;FETCH DATA&lt;/button&gt;
{data.map((user, index) =&gt; {
return (
&lt;div key={index}&gt;
{user.email}
&lt;img src={user.picture.medium} alt=&quot;&quot; /&gt;
&lt;/div&gt;
);
})}
&lt;/div&gt;
);
}

Otherwise, because your page is already a client component with &quot;use client&quot; at the top, you could simply use an useEffect to load the initial data, like so:

// app/page.js &#128072;&#127997;
&quot;use client&quot;;
import { useEffect, useState } from &quot;react&quot;;
export default function Page() {
const [data, setData] = useState([]);
const handleClick = async (event) =&gt; {
event.preventDefault();
const req = await fetch(&quot;https://randomuser.me/api/?gender=male&amp;results=100&quot;);
const newData = await req.json();
setData(newData.results);
};
useEffect(() =&gt; {
fetch(&quot;https://randomuser.me/api/?gender=female&amp;results=10&quot;)
.then((res) =&gt; res.json())
.then((data) =&gt; {
setData(data.results);
});
}, []);
return (
&lt;div&gt;
&lt;button onClick={handleClick}&gt;FETCH DATA&lt;/button&gt;
{data.map((user, index) =&gt; {
return (
&lt;div key={index}&gt;
{user.email}
&lt;img src={user.picture.medium} alt=&quot;&quot; /&gt;
&lt;/div&gt;
);
})}
&lt;/div&gt;
);
}

答案2

得分: 0

getInitialProps现在是一个遗留的API,文档建议使用getStaticPropsgetServerSideProps。但由于在应用程序路由器中都不受支持,可以尝试以下方法:

创建一个服务器组件作为父组件,在其中获取初始数据,然后将其传递给客户端组件,客户端组件可以处理所有客户端操作。

服务器组件

export async function ServerComponent() {
    const req = await fetch('https://randomuser.me/api/?gender=female&results=10');
    const data = await req.json();

    return (
        <ClientComponent initialData={data.results} />
    )
}

客户端组件

"use client";

export function ClientComponent({ 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 (
        <div>
            <button onClick={handleClick}>FETCH DATA</button>
            {data.map((user) => {
                return (
                    <div>
                        {user.email}
                        <img src={user.picture.medium} alt="" />
                    </div>
                );
            })}
        </div>
    );
}
英文:

getInitialProps is now a legacy API and the documentation recommends using getStaticProps and getServerSideProps. But since both are not supported in app router, try this instead:

Create a server component as a parent where you fetch the initial data and then pass it to the client component where all the client-side operations can be handled.

Server Component

export async function ServerComponent() {
const req = await fetch(&#39;https://randomuser.me/api/?gender=female&amp;results=10&#39;);
const data = await req.json();
return (
&lt;ClientComponent initialData={data.results} /&gt;
)
}

Client Component

&quot;use client&quot;;
export function ClientComponent({ initialData }) {
const [data, setData] = useState(initialData);
const fetchData = async () =&gt; {
const req = await fetch(
&quot;https://randomuser.me/api/?gender=male&amp;results=100&quot;
);
const newData = await req.json();
return setData(newData.results);
};
const handleClick = (event) =&gt; {
event.preventDefault();
fetchData();
};
return (
&lt;div&gt;
&lt;button onClick={handleClick}&gt;FETCH DATA&lt;/button&gt;
{data.map((user) =&gt; {
return (
&lt;div&gt;
{user.email}
&lt;img src={user.picture.medium} alt=&quot;&quot; /&gt;
&lt;/div&gt;
);
})}
&lt;/div&gt;
);
}
</details>

huangapple
  • 本文由 发表于 2023年7月24日 00:39:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76749325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定