MST
星途 面试题库

面试题:Next.js 页面路由的动态参数变更时,React 组件生命周期如何配合实现高效更新?

在 Next.js 应用中,有一个带动态参数的页面路由 `/posts/[id]`。当 `id` 参数发生变化时,组件需要重新获取对应文章的数据。请详细阐述如何结合 React 组件生命周期(如 `getInitialProps`、`componentDidMount` 等)来实现这一过程,同时保证数据获取的高效性,避免不必要的重复请求。
31.2万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试
  1. 使用 getInitialProps
    • getInitialProps 是 Next.js 特有的静态方法,在服务器端和客户端都会执行。
    • 当页面路由变化(id 参数变化)时,Next.js 会重新调用这个方法。
    • 代码示例:
import React from'react';

const Post = ({ post }) => {
    return (
        <div>
            <h1>{post.title}</h1>
            <p>{post.content}</p>
        </div>
    );
};

Post.getInitialProps = async ({ query }) => {
    const response = await fetch(`https://api.example.com/posts/${query.id}`);
    const post = await response.json();
    return { post };
};

export default Post;
  • 优点:在服务器端渲染时就可以获取数据,有利于 SEO。数据获取在组件实例化之前,减少了不必要的客户端请求。
  • 缺点:如果页面已经在客户端渲染,并且 id 参数变化,getInitialProps 会再次在客户端执行,可能会有重复请求。
  1. 结合 componentDidMountuseEffect(针对客户端优化)
    • 在客户端,componentDidMount(类组件)或 useEffect(函数组件)可以用来监听 id 参数的变化。
    • 对于函数组件,可以使用 useEffect 结合 useState 来管理数据。
    • 代码示例:
import React, { useState, useEffect } from'react';

const Post = ({ initialId }) => {
    const [post, setPost] = useState(null);
    const [currentId, setCurrentId] = useState(initialId);

    useEffect(() => {
        const fetchData = async () => {
            const response = await fetch(`https://api.example.com/posts/${currentId}`);
            const data = await response.json();
            setPost(data);
        };
        fetchData();
    }, [currentId]);

    useEffect(() => {
        setCurrentId(initialId);
    }, [initialId]);

    return (
        <div>
            {post && (
                <div>
                    <h1>{post.title}</h1>
                    <p>{post.content}</p>
                </div>
            )}
        </div>
    );
};

Post.getInitialProps = async ({ query }) => {
    return { initialId: query.id };
};

export default Post;
  • 优点:通过 useEffect 的依赖数组,可以精准控制数据获取时机,避免不必要的重复请求。在客户端可以更灵活地处理参数变化后的请求。
  • 缺点:相比纯 getInitialProps,在服务器端渲染时可能会有一些额外的逻辑处理。
  1. 缓存机制
    • 为了进一步避免重复请求,可以实现一个简单的缓存机制。
    • 例如,使用一个全局变量来存储已经获取的数据。
    • 代码示例(修改 getInitialProps 部分):
let cache = {};

Post.getInitialProps = async ({ query }) => {
    if (!cache[query.id]) {
        const response = await fetch(`https://api.example.com/posts/${query.id}`);
        const post = await response.json();
        cache[query.id] = post;
    }
    return { post: cache[query.id] };
};
  • 优点:有效减少重复请求,提高数据获取效率。
  • 缺点:需要注意缓存的清理和更新,防止数据过时。