面试题答案
一键面试设计思路
- 理解增量静态再生原理:增量静态再生允许在页面构建后重新生成静态页面,在指定的时间间隔内或基于某些事件。
- 数据一致性:
- 共享数据层:使用共享的数据获取逻辑,确保父路由和子路由获取数据的来源一致。例如,可以创建一个公共的数据获取函数,在父路由和子路由页面中复用。
- 依赖跟踪:当父路由参数变化时,建立一种机制来跟踪子路由页面所依赖的数据变化。可以通过上下文(Context)或者全局状态管理工具(如Redux)来实现。
- 高效加载:
- 缓存策略:利用HTTP缓存机制,设置合适的缓存头(如
Cache - Control
)。对于静态资源,可以设置较长的缓存时间;对于动态数据,根据其变化频率设置合理的缓存时间。 - 避免重复请求:在客户端层面,使用数据缓存库(如
swr
或react - query
),它们可以自动管理缓存,避免重复请求相同的数据。在服务端,使用中间件(如Next.js
的next - server - api - route - cache
)来缓存API响应。
- 缓存策略:利用HTTP缓存机制,设置合适的缓存头(如
具体实现方法
- 共享数据获取函数:
- 在项目中创建一个
lib/api
目录,例如lib/api/fetchData.js
。
export async function fetchMyData(params) { const response = await fetch(`https://example.com/api/data?${new URLSearchParams(params).toString()}`); return response.json(); }
- 在父路由页面(如
pages/parent/[parentId].js
)和子路由页面(如pages/parent/[parentId]/child/[childId].js
)中导入并使用这个函数。
import { fetchMyData } from '@/lib/api/fetchData'; export async function getStaticProps({ params }) { const data = await fetchMyData({ parentId: params.parentId }); return { props: { data }, revalidate: 60 // 每60秒重新验证 }; } const ParentPage = ({ data }) => { // 页面渲染逻辑 }; export default ParentPage;
- 在项目中创建一个
- 依赖跟踪:
- 使用上下文:创建一个上下文(
Context
)来传递父路由参数和相关数据状态。
import { createContext } from'react'; const ParentDataContext = createContext(); export default ParentDataContext;
- 在父路由页面中,将数据和参数通过上下文传递给子路由。
import ParentDataContext from '@/context/ParentDataContext'; export async function getStaticProps({ params }) { const data = await fetchMyData({ parentId: params.parentId }); return { props: { data }, revalidate: 60 }; } const ParentPage = ({ data }) => { return ( <ParentDataContext.Provider value={{ data, parentId: data.parentId }}> {/* 子路由部分 */} </ParentDataContext.Provider> ); }; export default ParentPage;
- 在子路由页面中,通过上下文获取数据,避免重复请求。
import ParentDataContext from '@/context/ParentDataContext'; import { useContext } from'react'; const ChildPage = () => { const { data } = useContext(ParentDataContext); // 子路由页面使用数据渲染 return ( <div> {data.childData} </div> ); }; export default ChildPage;
- 使用上下文:创建一个上下文(
- 缓存策略:
- HTTP缓存头:在
next.config.js
中设置缓存头。
module.exports = { async headers() { return [ { source: '/api/:path*', headers: [ { key: 'Cache - Control', value: 'public, max - age = 3600' } ] } ]; } };
- 客户端缓存:使用
swr
库。首先安装swr
:npm install swr
。
import useSWR from'swr'; import { fetchMyData } from '@/lib/api/fetchData'; const ChildPage = () => { const { data, error } = useSWR(['/api/data', { parentId: '123' }], fetchMyData); if (error) return <div>Error loading data</div>; if (!data) return <div>Loading...</div>; return ( <div> {data.childData} </div> ); }; export default ChildPage;
- 服务端缓存:使用
next - server - api - route - cache
库。安装:npm install next - server - api - route - cache
。在API路由中使用:
import nc from 'next - connect'; import { cache } from 'next - server - api - route - cache'; import { fetchMyData } from '@/lib/api/fetchData'; const handler = nc(); cache(handler, { cacheControl: 'public, s - maxage = 3600, stale - while - revalidate = 60', keys: (req) => [req.query.parentId] }); handler.get(async (req, res) => { const data = await fetchMyData({ parentId: req.query.parentId }); res.json(data); }); export default handler;
- HTTP缓存头:在