React面试题及详细答案150道(51-60)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux... 。

前后端面试题-专栏总目录

文章目录

  • 一、本文面试题目录
      • [51. 如何在React中实现无限滚动(Infinite Scroll)?](#51. 如何在React中实现无限滚动(Infinite Scroll)?)
      • [52. React中的useCallback和useMemo有什么区别?](#52. React中的useCallback和useMemo有什么区别?)
      • [53. 什么是React的Context API?如何避免Context导致的性能问题?](#53. 什么是React的Context API?如何避免Context导致的性能问题?)
      • [54. 如何在React中实现组件的条件渲染?](#54. 如何在React中实现组件的条件渲染?)
      • [55. 如何在React中实现状态持久化?](#55. 如何在React中实现状态持久化?)
      • [56. 如何在React中实现状态管理?除了Redux还有哪些方案?](#56. 如何在React中实现状态管理?除了Redux还有哪些方案?)
      • [57. 什么是React的StrictMode?它有什么作用?](#57. 什么是React的StrictMode?它有什么作用?)
      • [58. 如何在React中优化大型列表渲染性能?](#58. 如何在React中优化大型列表渲染性能?)
      • [59. 如何在React中实现暗黑模式(Dark Mode)?](#59. 如何在React中实现暗黑模式(Dark Mode)?)
      • [60. 如何在React中实现WebSocket通信?](#60. 如何在React中实现WebSocket通信?)

一、本文面试题目录

51. 如何在React中实现无限滚动(Infinite Scroll)?

无限滚动实现方案

  1. 基于滚动事件监听

    jsx 复制代码
    const [items, setItems] = useState(initialItems);
    const [page, setPage] = useState(1);
    const [isLoading, setIsLoading] = useState(false);
    
    useEffect(() => {
      const handleScroll = () => {
        if (
          window.innerHeight + document.documentElement.scrollTop >=
          document.documentElement.offsetHeight - 500 &&
          !isLoading
        ) {
          setIsLoading(true);
          fetchMoreData(page + 1).then(newItems => {
            setItems([...items, ...newItems]);
            setPage(page + 1);
            setIsLoading(false);
          });
        }
      };
    
      window.addEventListener('scroll', handleScroll);
      return () => window.removeEventListener('scroll', handleScroll);
    }, [items, page, isLoading]);
    
    return (
      <div>
        {items.map(item => <Item key={item.id} {...item} />)}
        {isLoading && <div>Loading...</div>}
      </div>
    );
  2. 使用Intersection Observer API

    jsx 复制代码
    const [items, setItems] = useState(initialItems);
    const [isLoading, setIsLoading] = useState(false);
    const observer = useRef(null);
    
    const loadMoreRef = useCallback(node => {
      if (isLoading) return;
      if (observer.current) observer.current.disconnect();
      
      observer.current = new IntersectionObserver(entries => {
        if (entries[0].isIntersecting) {
          setIsLoading(true);
          fetchMoreData().then(newItems => {
            setItems([...items, ...newItems]);
            setIsLoading(false);
          });
        }
      });
    
      if (node) observer.current.observe(node);
    }, [isLoading, items]);
    
    return (
      <div>
        {items.map(item => <Item key={item.id} {...item} />)}
        <div ref={loadMoreRef}>{isLoading ? 'Loading...' : 'Load more'}</div>
      </div>
    );

52. React中的useCallback和useMemo有什么区别?

核心区别

  • useCallback:缓存函数引用,避免组件重新渲染时创建新函数
  • useMemo:缓存计算结果,避免重复计算

使用场景

  • useCallback

    jsx 复制代码
    const memoizedCallback = useCallback(
      () => doSomething(a, b),
      [a, b]
    );
  • useMemo

    jsx 复制代码
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

53. 什么是React的Context API?如何避免Context导致的性能问题?

Context API 用于跨层级传递数据,避免props drilling。

性能优化

  1. 拆分Context

    jsx 复制代码
    // 分离高频变化和低频变化的context
    const UserContext = React.createContext();
    const ThemeContext = React.createContext();
    
    <UserContext.Provider value={user}>
      <ThemeContext.Provider value={theme}>
        <App />
      </ThemeContext.Provider>
    </UserContext.Provider>
  2. 使用useMemo缓存Provider值

    jsx 复制代码
    const themeValue = useMemo(() => ({ theme, setTheme }), [theme]);
    <ThemeContext.Provider value={themeValue}>
      {children}
    </ThemeContext.Provider>
  3. 避免在Provider中使用内联对象

    jsx 复制代码
    // 不好的写法
    <MyContext.Provider value={{ count, setCount }}>
    
    // 优化:使用useMemo缓存对象
    const contextValue = useMemo(() => ({ count, setCount }), [count]);
    <MyContext.Provider value={contextValue}>

54. 如何在React中实现组件的条件渲染?

条件渲染方式

  1. if-else语句

    jsx 复制代码
    function Greeting(props) {
      if (props.isLoggedIn) {
        return <h1>Welcome back!</h1>;
      }
      return <h1>Please sign in.</h1>;
    }
  2. 三元运算符

    jsx 复制代码
    return (
      <div>
        {isLoading ? (
          <Spinner />
        ) : (
          <Content />
        )}
      </div>
    );
  3. 逻辑与运算符(&&)

    jsx 复制代码
    return (
      <div>
        {unreadMessages.length > 0 && (
          <h2>You have {unreadMessages.length} unread messages.</h2>
        )}
      </div>
    );
  4. 状态变量控制

    jsx 复制代码
    const [showComponent, setShowComponent] = useState(false);
    
    return (
      <div>
        <button onClick={() => setShowComponent(!showComponent)}>
          Toggle Component
        </button>
        {showComponent && <MyComponent />}
      </div>
    );

55. 如何在React中实现状态持久化?

状态持久化实现

  1. localStorage + useEffect

    jsx 复制代码
    const [count, setCount] = useState(() => {
      const saved = localStorage.getItem('count');
      return saved ? JSON.parse(saved) : 0;
    });
    
    useEffect(() => {
      localStorage.setItem('count', JSON.stringify(count));
    }, [count]);
  2. 自定义Hook封装

    jsx 复制代码
    function useLocalStorage(key, initialValue) {
      const [value, setValue] = useState(() => {
        const saved = localStorage.getItem(key);
        return saved ? JSON.parse(saved) : initialValue;
      });
    
      useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
      }, [key, value]);
    
      return [value, setValue];
    }
    
    // 使用
    const [count, setCount] = useLocalStorage('count', 0);

56. 如何在React中实现状态管理?除了Redux还有哪些方案?

状态管理方案

  1. React内置方案

    • useState/useReducer(局部状态)
    • Context API(全局状态)
  2. 第三方库

    • Redux(复杂应用,单向数据流)
    • MobX(响应式状态管理,基于装饰器)
    • Zustand(轻量级,函数式API)
    • Recoil(Facebook开发,原子化状态)
    • Jotai(极简,原子化状态)
  3. 示例(使用Zustand)

    jsx 复制代码
    import create from 'zustand';
    
    const useCounterStore = create((set) => ({
      count: 0,
      increment: () => set((state) => ({ count: state.count + 1 })),
      decrement: () => set((state) => ({ count: state.count - 1 })),
    }));
    
    // 使用store
    function Counter() {
      const count = useCounterStore((state) => state.count);
      const increment = useCounterStore((state) => state.increment);
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={increment}>+1</button>
        </div>
      );
    }

57. 什么是React的StrictMode?它有什么作用?

StrictMode 是一个用于检测潜在问题的开发工具,仅在开发环境生效:

检测内容

  1. 不推荐的API使用

    • 废弃的生命周期方法(如componentWillReceiveProps
    • 不安全的findDOMNode使用
    • 过时的context API
  2. 副作用验证

    • 检查useEffect是否正确清除副作用
    • 检测意外的副作用(通过两次调用函数组件)
  3. 安全检查

    • 确保状态初始化纯净
    • 验证getDerivedStateFromProps的使用

启用方式

jsx 复制代码
<React.StrictMode>
  <App />
</React.StrictMode>

58. 如何在React中优化大型列表渲染性能?

列表性能优化

  1. 虚拟列表(Virtualization)

    jsx 复制代码
    import { FixedSizeList } from'react-window';
    
    const Row = ({ index, style }) => {
      return (
        <div style={style}>
          Row {index}: {data[index]}
        </div>
      );
    };
    
    const List = () => (
      <FixedSizeList
        height={600}
        width={800}
        itemSize={35}
        itemCount={data.length}
      >
        {Row}
      </FixedSizeList>
    );
  2. 使用memo防止不必要的重渲染

    jsx 复制代码
    const MemoizedItem = memo(({ item }) => (
      <div>{item.name}</div>
    ));
    
    // 列表渲染
    {items.map((item) => (
      <MemoizedItem key={item.id} item={item} />
    ))}

59. 如何在React中实现暗黑模式(Dark Mode)?

暗黑模式实现

  1. CSS变量 + Context API

    jsx 复制代码
    // ThemeContext.js
    export const ThemeContext = React.createContext();
    
    const ThemeProvider = ({ children }) => {
      const [theme, setTheme] = useState('light');
      const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');
    
      return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
          {children}
        </ThemeContext.Provider>
      );
    };
    
    // 全局样式
    :root {
      --bg-color: #ffffff;
      --text-color: #000000;
    }
    
    .dark-mode {
      --bg-color: #1a1a1a;
      --text-color: #ffffff;
    }
    
    // 使用
    <div className={theme === 'dark' ? 'dark-mode' : ''}>
      <p style={{ color: 'var(--text-color)' }}>Hello World</p>
    </div>

60. 如何在React中实现WebSocket通信?

WebSocket实现

  1. 使用useState和useEffect

    jsx 复制代码
    const [messages, setMessages] = useState([]);
    const [socket, setSocket] = useState(null);
    
    useEffect(() => {
      const ws = new WebSocket('ws://localhost:8080');
      setSocket(ws);
    
      ws.onmessage = (event) => {
        setMessages((prev) => [...prev, JSON.parse(event.data)]);
      };
    
      return () => {
        ws.close();
      };
    }, []);
    
    const sendMessage = (message) => {
      socket?.send(JSON.stringify(message));
    };
  2. 自定义Hook封装WebSocket逻辑

    jsx 复制代码
    function useWebSocket(url) {
      const [messages, setMessages] = useState([]);
      const socketRef = useRef(null);
    
      useEffect(() => {
        socketRef.current = new WebSocket(url);
    
        socketRef.current.onmessage = (event) => {
          setMessages((prev) => [...prev, JSON.parse(event.data)]);
        };
    
        return () => {
          socketRef.current.close();
        };
      }, [url]);
    
      const sendMessage = (message) => {
        socketRef.current.send(JSON.stringify(message));
      };
    
      return { messages, sendMessage };
    }
    
    // 使用
    function Chat() {
      const { messages, sendMessage } = useWebSocket('ws://localhost:8080');
      return (
        <div>
          {messages.map((msg) => (
            <div key={msg.id}>{msg.text}</div>
          ))}
          <button onClick={() => sendMessage({ text: 'Hello' })}>Send</button>
        </div>
      );
    }
相关推荐
10share2 小时前
React组件间通信
react.js
是一碗螺丝粉3 小时前
React Native 运行时深度解析
前端·react native·react.js
骑自行车的码农3 小时前
🍂 React DOM树的构建原理和算法
javascript·算法·react.js
前端老宋Running1 天前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
4***14901 天前
TypeScript在React中的前端框架
react.js·typescript·前端框架
y***54881 天前
TypeScript在React项目中的状态管理
javascript·react.js·typescript
努力往上爬de蜗牛1 天前
react native真机调试
javascript·react native·react.js
小猪努力学前端2 天前
在 React + React Router v7 SSR 项目里做多端适配,我踩的两个坑
前端·react.js
weixin79893765432...2 天前
Electron + React + Vite 实践
react.js·electron·vite