面试备战录

54 阅读3分钟

1、什么是 JSX?为什么要使用?

答:JSXReact中用于描述UI的一种扩展语法,它允许我们在JS中书写类HTML的结构。本质上JSXReact.createElement的语法糖,最终会被 Babel 编译成纯 JavaScript 函数调用。

JSX 的优点:

  • 可读性:像写 HTML 一样写组件结构,更直观,更清晰;
  • 组件化开发友好:模版和逻辑写在一起,便于组织组件;
  • 强类型支持:配合TypeScript使用,能提供更好的开发体验;
  • 支持JS表达式:{}包裹后可直接写变量、函数、三元表达式等逻辑;
  • 工具链生态丰富:JSX 与 Babel、ESlint 等无缝集成,方便做编译、提示和格式化。

2、useCallbackuseMemo的区别?

答:useMemo用来缓存计算结果,避免在依赖没变化时重新计算;useCallback是缓存函数的引用,防止函数因为组件重新渲染而重复重建。它们都用于性能优化,前者优化值计算,后者优化函数传递,尤其在传递给子组件时很有用。

  • useMemo:缓存值(结果)
// 当 data 不变时,不会重新执行 heavyCalculation()
const expensiveValue = useMemo(() => {
  return heavyCalculation(data); // 耗时操作
}, [data]);
  • useCallback:缓存函数(引用)
// 防止每次渲染都创建一个新函数,尤其在传给子组件时,避免不必要的 re-render
const handleClick = useCallback(() => {
  console.log('Clicked!');
}, []);

3、React.memo 如何工作?是否可以比较深层对象?

答:React.memoReact提供的一个高阶组件,用于对函数组件进行性能优化。

  • React.memo会对传入的props进行浅比较(shallow comparison)
  • 如果前后props没有变化,就跳过重新渲染,直接复用上次的渲染结果。
  • 它只对props层面进行优化,不关心组件内部的statecontext
  • 可以传递第二个参数,一个自定义比较函数。

4、React 中如何避免不必要的重新渲染?

  1. 使用 React.memo用于组件
  • 作用:缓存函数组件的渲染结果,当 props 没变时跳过重新渲染。
  • 适用场景:纯展示组件、接收固定 props 的子组件
const MyComponent = React.memo(function MyComponent({ name }) {
  return <div>{name}</div>;
});
  1. 使用useMemo(缓存计算结果)
  • 作用:缓存一个计算过程(如复杂计算或依赖于 props 的列表过滤等),避免每次渲染都重复计算。
  • 注意:仅在性能瓶颈处使用,滥用反而有开销。
const filteredList = useMemo(() => {
  return list.filter(item => item.visible);
}, [list]);
  1. 使用useCallback(缓存函数引用)
  • 作用:防止每次组件渲染都创建新的函数引用,传递给子组件时尤其重要。
// 如果将函数作为 props 传给 React.memo 包裹的子组件,不加 useCallback 会导致子组件每次都重新渲染。
const handleClick = useCallback(() => {
  // do something
}, [deps]);
  1. 父组件中避免不必要的state/props更新
  • 例子:不要频繁 setState 引起全量更新;按需拆分 state。
// bad: 会触发组件重渲染,即使 b 没变
setState({ a: 1, b: 2 });
  1. 使用 key 正确管理列表渲染
  • React 依赖 key 区分 DOM 节点,不稳定的 key(如 index)会导致重复渲染 DOM。
  1. 避免匿名函数、对象、数组直接写在 JSX 中
  • 每次 render 都会新建引用,影响 React.memo、useEffect 的依赖比较。
  1. 合理拆分组件
  • 将大型组件拆成多个小组件,独立控制渲染范围,减少重渲染影响。