英文:
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.
'use client'
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}>FETCH DATA</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 };
};
答案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 👈🏽
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} />;
}
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 👈🏽
"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>
);
}
Otherwise, because your page is already a client component with "use client"
at the top, you could simply use an useEffect
to load the initial data, like so:
// 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>
);
}
答案2
得分: 0
getInitialProps
现在是一个遗留的API,文档建议使用getStaticProps
和getServerSideProps
。但由于在应用程序路由器中都不受支持,可以尝试以下方法:
创建一个服务器组件作为父组件,在其中获取初始数据,然后将其传递给客户端组件,客户端组件可以处理所有客户端操作。
服务器组件
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('https://randomuser.me/api/?gender=female&results=10');
const data = await req.json();
return (
<ClientComponent initialData={data.results} />
)
}
Client Component
"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>
);
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论