MST

星途 面试题库

面试题:如何基于React Context实现一个可动态切换主题的系统且保证性能最优?

要求实现一个React应用,具备可动态切换主题(如亮色主题和暗色主题)的功能,通过React Context在多层组件间传递主题相关数据。不仅要完成功能实现,还需详细说明如何通过各种手段(如shouldComponentUpdate、React.memo等)确保在主题切换及组件更新过程中性能达到最优。请给出完整的设计思路及核心代码片段。
39.5万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 创建主题Context:使用React.createContext创建一个上下文对象,用于在组件树中传递主题相关数据。
  2. 主题切换逻辑:在顶层组件中维护一个状态来表示当前主题,并提供切换主题的函数。
  3. 性能优化
    • shouldComponentUpdate:在类组件中,通过shouldComponentUpdate方法,根据主题是否变化来决定是否重新渲染组件。
    • React.memo:在函数组件中,使用React.memo包裹组件,当props没有变化时,阻止组件重新渲染。对于仅依赖主题的子组件,确保只有主题变化时才重新渲染。

核心代码片段

  1. 创建主题Context
import React from 'react';

const ThemeContext = React.createContext();

export default ThemeContext;
  1. 主题切换逻辑及顶层组件
import React, { useState } from'react';
import ThemeContext from './ThemeContext';
import ChildComponent from './ChildComponent';

const App = () => {
    const [theme, setTheme] = useState('light');

    const toggleTheme = () => {
        setTheme(theme === 'light'? 'dark' : 'light');
    };

    return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
            <ChildComponent />
        </ThemeContext.Provider>
    );
};

export default App;
  1. 子组件使用Context并进行性能优化
import React from'react';
import ThemeContext from './ThemeContext';

// 函数组件使用React.memo进行性能优化
const ChildComponent = React.memo((props) => {
    const { theme, toggleTheme } = React.useContext(ThemeContext);
    return (
        <div>
            <p>Current theme: {theme}</p>
            <button onClick={toggleTheme}>Toggle Theme</button>
        </div>
    );
});

export default ChildComponent;
  1. 类组件使用shouldComponentUpdate进行性能优化
import React from'react';
import ThemeContext from './ThemeContext';

class ClassChildComponent extends React.Component {
    static contextType = ThemeContext;

    shouldComponentUpdate(nextProps, nextState) {
        const { theme } = this.context;
        const { theme: nextTheme } = nextProps;
        return theme!== nextTheme;
    }

    render() {
        const { theme, toggleTheme } = this.context;
        return (
            <div>
                <p>Current theme: {theme}</p>
                <button onClick={toggleTheme}>Toggle Theme</button>
            </div>
        );
    }
}

export default ClassChildComponent;