next.js getInitialProps在获取初始数据并在稍后使用按钮更新时没有向页面组件发送数据

iyr7buue  于 2023-08-04  发布在  其他
关注(0)|答案(2)|浏览(80)

我在Next.js v13.4.12中的app\page.tsx处有一个组件,包含一个按钮。当我点击它时,我希望它调用handleClick函数。
但是函数getInitialProps没有被调用,也没有向Page组件发送props,我该怎么办?
事实上,我想当页面第一次呈现时,即使我们没有点击按钮,数据也会呈现在页面上。

'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 };
};

字符串

rt4zxlrg

rt4zxlrg1#

getServerSidePropsgetStaticProps这样的方法用于在服务器上获取数据,但它们只对pages文件夹中的页面组件有效(在Next.js中设置路由的初始方式)。
从Next.js 13开始,在app目录中,我们有服务器组件,在那里你可以直接在组件体中获取数据,在那里你想要实现的将如下所示(注意创建的附加文件):

// 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>
  );
}

lg40wkob

lg40wkob2#

getInitialProps现在是一个遗留API,文档建议使用getStaticPropsgetServerSideProps。但由于app router不支持这两种方法,请尝试以下操作:
创建一个服务器组件作为父组件,从中获取初始数据,然后将其传递给客户端组件,在客户端组件中可以处理所有客户端操作。
服务器组件

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>
  );
}

相关问题