面试题答案
一键面试利用动态导入与懒加载优化路由加载
- 动态导入路由组件:
在 Next.js 中,使用
next/router
进行路由跳转时,可以通过动态导入组件的方式实现懒加载。例如,在pages
目录下的某个页面中,假设存在一个不常访问的子路由页面UncommonPage
:
import { useRouter } from 'next/router';
const MyPage = () => {
const router = useRouter();
const handleClick = () => {
// 动态导入 UncommonPage 组件
import('../pages/UncommonPage').then((module) => {
router.push('/uncommon-page');
});
};
return (
<div>
<button onClick={handleClick}>Go to Uncommon Page</button>
</div>
);
};
export default MyPage;
这样,UncommonPage
组件只有在用户点击按钮触发 handleClick
函数时才会被加载,而不是在页面初始加载时就加载。
- 基于路由的动态导入:
Next.js 支持在
pages
目录结构中通过约定式路由来实现动态导入。例如,对于动态路由页面pages/post/[id].js
,当访问具体的post
页面时,对应的组件才会被加载:
// pages/post/[id].js
import React from'react';
const PostPage = ({ id }) => {
return (
<div>
<h1>Post {id}</h1>
</div>
);
};
export default PostPage;
Next.js 会在需要时动态导入这个组件,而不是在应用启动时加载所有可能的 post
页面组件。
处理动态导入组件的样式加载
- CSS - in - JS 方案:
如果使用 CSS - in - JS 库,如
styled - components
或emotion
,样式会随着组件的导入而自动加载。例如,使用styled - components
:
import React from'react';
import styled from'styled - components';
const StyledDiv = styled.div`
background - color: lightblue;
padding: 20px;
`;
const DynamicComponent = () => {
return (
<StyledDiv>
This is a dynamically imported component with its own style.
</StyledDiv>
);
};
export default DynamicComponent;
当该组件被动态导入时,styled - components
会自动将样式添加到文档中。
- CSS Modules:
对于 CSS Modules,需要确保在组件导入时正确引入样式。例如,在
DynamicComponent.module.css
中定义样式:
/* DynamicComponent.module.css */
.container {
background - color: lightgreen;
padding: 15px;
}
在组件中导入样式:
import React from'react';
import styles from './DynamicComponent.module.css';
const DynamicComponent = () => {
return (
<div className={styles.container}>
This is a dynamically imported component with CSS Modules style.
</div>
);
};
export default DynamicComponent;
当组件被动态导入时,相关的 CSS Modules 样式也会生效。
处理动态导入组件的数据预取
- getStaticProps 与 getStaticPaths:
对于静态生成的页面(使用
getStaticProps
和getStaticPaths
),可以在这些函数中进行数据预取。例如,对于一个博客文章页面pages/blog/[slug].js
:
import React from'react';
import { getAllPosts } from '../lib/api';
const BlogPost = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
export async function getStaticPaths() {
const posts = await getAllPosts();
const paths = posts.map((post) => ({
params: { slug: post.slug }
}));
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
const post = await getAllPosts().then((posts) => posts.find((p) => p.slug === params.slug));
return {
props: {
post
},
revalidate: 60 // 可选,用于增量静态再生
};
}
export default BlogPost;
在这种情况下,Next.js 会在构建时预取数据,并将数据传递给组件。当动态导入这个页面组件时,数据已经准备好。
- getServerSideProps:
如果需要在每次请求时获取最新数据,可以使用
getServerSideProps
。例如:
import React from'react';
import { getPost } from '../lib/api';
const BlogPost = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
export async function getServerSideProps({ params }) {
const post = await getPost(params.slug);
return {
props: {
post
}
};
}
export default BlogPost;
当动态导入这个组件时,getServerSideProps
会在服务器端运行,获取最新数据并传递给组件。