面试题答案
一键面试设计思路
- 样式隔离:
- 使用 CSS Modules 或 styled - components 等方案。CSS Modules 通过将 CSS 类名进行本地化处理,避免全局样式冲突;styled - components 以 JavaScript 方式编写样式,同样实现样式隔离。
- 对于第三方组件,可以采用 Shadow DOM 的 polyfill 或者类似的技术来隔离其样式,确保与应用内其他样式互不干扰。
- 组件复用:
- 遵循单一职责原则,将组件拆分成尽可能小且功能独立的模块。例如,将一个复杂的表单组件拆分成输入框、按钮、标签等基础组件。
- 创建一个组件库,集中管理可复用组件。组件库可以按照功能模块进行分类,方便查找和使用。
- 性能优化:
- 对于样式,采用按需加载。例如,在 Next.js 中可以利用 dynamic 导入组件,同时加载对应的样式,避免一开始就加载大量不必要的样式。
- 对于组件,使用 memoization 技术。在 React 中,使用
React.memo
包裹纯函数组件,避免不必要的重新渲染。
- 开发效率:
- 建立规范的开发流程和代码结构,例如使用 ESLint 和 Prettier 来保证代码风格统一,减少代码审查时间。
- 采用自动化工具,如 Storybook,用于开发和测试组件,提高组件开发的可视化程度和效率。
具体实现步骤
- 样式隔离:
- CSS Modules:
- 在 Next.js 项目中,创建
.module.css
文件,例如Button.module.css
。 - 在组件中引入该 CSS Module 文件,如:
- 在 Next.js 项目中,创建
- CSS Modules:
import React from'react';
import styles from './Button.module.css';
const Button = () => {
return <button className={styles.button}>Click me</button>;
};
export default Button;
- styled - components:
- 安装
styled - components
库:npm install styled - components
。 - 在组件中使用,例如:
- 安装
import React from'react';
import styled from'styled - components';
const StyledButton = styled.button`
background - color: blue;
color: white;
`;
const Button = () => {
return <StyledButton>Click me</StyledButton>;
};
export default Button;
- 组件复用:
- 组件拆分:以一个导航栏组件为例,将其拆分成导航项、菜单按钮等组件。
// NavItem.js
import React from'react';
const NavItem = ({ text, href }) => {
return <a href={href}>{text}</a>;
};
export default NavItem;
// MenuButton.js
import React from'react';
const MenuButton = () => {
return <button>Menu</button>;
};
export default MenuButton;
// Navbar.js
import React from'react';
import NavItem from './NavItem';
import MenuButton from './MenuButton';
const Navbar = () => {
return (
<nav>
<MenuButton />
<NavItem text="Home" href="/" />
<NavItem text="About" href="/about" />
</nav>
);
};
export default Navbar;
- 组件库搭建:创建一个
components
目录,在其中按照功能模块再细分目录,如ui
、layout
等。将可复用组件放置在相应目录下,并编写文档说明组件的使用方法和参数。
- 性能优化:
- 样式按需加载:在 Next.js 中,使用
next/dynamic
动态导入组件,同时可以在动态导入的回调函数中导入样式。例如:
- 样式按需加载:在 Next.js 中,使用
import dynamic from 'next/dynamic';
const BigComponent = dynamic(() => import('./BigComponent'), {
loading: () => <div>Loading...</div>,
ssr: false
});
const Page = () => {
return (
<div>
<BigComponent />
</div>
);
};
export default Page;
在 BigComponent.js
中导入样式:
import React from'react';
import styles from './BigComponent.module.css';
const BigComponent = () => {
return <div className={styles.container}>Big Component</div>;
};
export default BigComponent;
- 组件 memoization:对于纯函数组件,使用
React.memo
包裹。例如:
import React from'react';
const MyComponent = ({ data }) => {
return <div>{data}</div>;
};
export default React.memo(MyComponent);
- 开发效率:
- 代码规范:安装 ESLint 和 Prettier,配置相应的
.eslintrc.json
和.prettierrc.json
文件。在package.json
中添加脚本:
- 代码规范:安装 ESLint 和 Prettier,配置相应的
{
"scripts": {
"lint": "eslint src",
"format": "prettier --write src"
}
}
- 使用 Storybook:安装 Storybook:
npx sb init
。在.storybook
目录下配置组件的 stories 文件,例如Button.stories.js
:
import React from'react';
import Button from './Button';
export default {
title: 'UI/Button',
component: Button
};
export const PrimaryButton = () => <Button>Primary</Button>;
通过 Storybook,可以在隔离环境中开发和测试组件,提高开发效率。