MST

星途 面试题库

面试题:React 条件渲染与性能优化

假设你正在开发一个大型 React 应用,其中有多个组件需要根据不同的条件进行渲染。例如,根据用户的权限(permissionLevel 为数字),可能会渲染出不同复杂度的组件树。有些组件渲染成本较高。请描述你会如何设计条件渲染逻辑,以确保在不同条件下应用的性能最优,包括减少不必要的重渲染,以及如何利用 React.memo 或 shouldComponentUpdate 等机制。
37.2万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 使用 React.memo 优化函数式组件
    • 对于那些渲染成本较高且 props 没有变化时不需要重新渲染的函数式组件,使用 React.memo 进行包裹。例如:
    const ExpensiveComponent = React.memo((props) => {
      // 复杂的渲染逻辑
      return <div>{props.value}</div>;
    });
    
    • React.memo 会浅比较组件的 props,如果 props 没有变化,组件不会重新渲染。但要注意,如果 props 是对象或数组,浅比较可能无法正确判断变化,此时可以使用自定义比较函数作为 React.memo 的第二个参数。例如:
    const compareProps = (prevProps, nextProps) => {
      return prevProps.value === nextProps.value;
    };
    const AnotherExpensiveComponent = React.memo((props) => {
      // 复杂的渲染逻辑
      return <div>{props.value}</div>;
    }, compareProps);
    
  2. 在类组件中使用 shouldComponentUpdate
    • 对于类组件,可以通过重写 shouldComponentUpdate 方法来控制组件是否需要重新渲染。例如:
    class LegacyExpensiveComponent extends React.Component {
      shouldComponentUpdate(nextProps, nextState) {
        return this.props.value!== nextProps.value;
      }
      render() {
        // 复杂的渲染逻辑
        return <div>{this.props.value}</div>;
      }
    }
    
    • 这里根据 props 中的 value 来判断是否需要更新。同样,对于复杂数据结构的比较,需要更细致的逻辑。
  3. 条件渲染逻辑设计
    • 减少不必要的重渲染:将条件判断尽量放在顶层,避免在子组件内部进行过多重复的条件判断。例如,不要在子组件中多次判断用户权限来决定渲染内容,而是在父组件一次性判断,然后传递相应的 props 给子组件。
    • 基于权限的组件树渲染
      const App = ({ permissionLevel }) => {
        let componentToRender;
        if (permissionLevel === 1) {
          componentToRender = <SimpleComponent />;
        } else if (permissionLevel === 2) {
          componentToRender = <MediumComplexityComponent />;
        } else if (permissionLevel >= 3) {
          componentToRender = <HighComplexityComponent />;
        }
        return <div>{componentToRender}</div>;
      };
      
    • 缓存渲染结果:如果某些条件渲染的组件树在相同条件下不会变化,可以考虑缓存渲染结果。例如,使用一个对象来存储不同权限级别对应的组件实例,在渲染时直接从缓存中获取。
    const componentCache = {};
    const App = ({ permissionLevel }) => {
      let componentToRender;
      if (!componentCache[permissionLevel]) {
        if (permissionLevel === 1) {
          componentCache[permissionLevel] = <SimpleComponent />;
        } else if (permissionLevel === 2) {
          componentCache[permissionLevel] = <MediumComplexityComponent />;
        } else if (permissionLevel >= 3) {
          componentCache[permissionLevel] = <HighComplexityComponent />;
        }
      }
      componentToRender = componentCache[permissionLevel];
      return <div>{componentToRender}</div>;
    };