Next.js13.4.12中getInitialProps失效,如何实现初始加载与数据更新?
问题原因
Next.js 13.4.12使用的**App Router(app目录)**完全弃用了Pages Router中的getInitialProps、getStaticProps等数据获取API,所以你写的Page.getInitialProps不会被调用。
解决方案
推荐采用App Router的原生方案,将数据获取和交互逻辑拆分,兼顾服务器端渲染的SEO优势和客户端交互需求:
方案1:服务器组件获取初始数据 + 客户端组件处理交互
这是App Router的最佳实践,初始数据在服务器端获取,交互逻辑放在客户端组件中。
1. 改造app/page.tsx为服务器组件
// app/page.tsx - 服务器组件,无需添加'use client' import UserList from './UserList'; // 服务器端直接获取初始数据 async function getInitialData() { const res = await fetch('https://randomuser.me/api/?gender=female&results=10', { // 根据需求选择缓存策略:force-cache(默认)/ no-store / revalidate cache: 'no-store', }); const data = await res.json(); return data.results; } export default async function Page() { const initialData = await getInitialData(); return <UserList initialData={initialData} />; }
2. 创建客户端组件app/UserList.tsx处理交互
// app/UserList.tsx - 客户端组件,必须添加'use client' 'use client'; import { useState } from 'react'; export default function UserList({ initialData }) { const [data, setData] = useState(initialData); const fetchData = async () => { const res = await fetch('https://randomuser.me/api/?gender=male&results=100'); const newData = await res.json(); setData(newData.results); }; const handleClick = (event) => { event.preventDefault(); fetchData(); }; return ( <div> <button onClick={handleClick}>FETCH DATA</button> {data.map((user) => ( <div key={user.login.uuid}> {user.email} <img src={user.picture.medium} alt={`${user.name.first} ${user.name.last}`} /> </div> ))} </div> ); }
方案2:纯客户端组件用useEffect初始化数据
如果不想拆分组件,可以直接在客户端组件中用useEffect在首次渲染时获取初始数据(缺点:初始数据由客户端请求,不利于SEO):
'use client'; import { useState, useEffect } from 'react'; export default function Page() { const [data, setData] = useState([]); // 首次渲染时获取初始数据 useEffect(() => { const fetchInitialData = async () => { const res = await fetch('https://randomuser.me/api/?gender=female&results=10'); const initialData = await res.json(); setData(initialData.results); }; fetchInitialData(); }, []); const fetchData = async () => { const res = await fetch('https://randomuser.me/api/?gender=male&results=100'); const newData = await res.json(); setData(newData.results); }; const handleClick = (event) => { event.preventDefault(); fetchData(); }; return ( <div> <button onClick={handleClick}>FETCH DATA</button> {data.map((user) => ( <div key={user.login.uuid}> {user.email} <img src={user.picture.medium} alt={`${user.name.first} ${user.name.last}`} /> </div> ))} </div> ); }
注意事项
- App Router中,
page.tsx默认是服务器组件,仅当需要使用React状态(useState)、副作用(useEffect)或事件绑定时,才需要添加'use client'标记。 - 列表渲染必须添加唯一的
key属性,避免React警告。
内容的提问来源于stack exchange,提问作者alireza kargar
相关产品推荐
相关产品推荐

