MST

星途 面试题库

面试题:复杂场景下如何选择useState或useReducer

假设你正在开发一个电商购物车功能,包含添加商品、删除商品、修改商品数量、计算总价等复杂交互逻辑,阐述在这种场景下,你会优先选择useState还是useReducer来管理购物车状态,并说明理由及如何进行状态管理。
23.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

在这种包含复杂交互逻辑的电商购物车功能场景下,优先选择 useReducer

理由

  1. 逻辑清晰useReducer 更适合管理包含多个子逻辑的复杂状态。对于购物车功能,添加、删除、修改数量等操作逻辑相对复杂,使用 useReducer 可以将这些操作集中在一个 reducer 函数中处理,使得代码结构更加清晰,易于维护。例如,在 reducer 函数中可以针对不同的 action 类型(如 ADD_ITEMREMOVE_ITEMUPDATE_QUANTITY 等)进行不同的状态更新逻辑处理。
  2. 可追溯性useReduceraction 机制提供了更好的可追溯性。每个状态变化都是由一个明确的 action 触发,方便进行调试和状态跟踪。当出现问题时,可以很容易地找到是哪个 action 导致了状态的错误变化。
  3. 性能优化:在某些情况下,useReducer 可以通过减少不必要的重新渲染来优化性能。例如,可以使用 React.memouseReducer 结合,在 action 没有改变依赖值时,避免组件的不必要重新渲染。

状态管理实现

  1. 定义状态结构
// 定义购物车商品项的类型
type CartItem = {
  id: string;
  name: string;
  price: number;
  quantity: number;
};

// 定义购物车状态类型
type CartState = {
  items: CartItem[];
  totalPrice: number;
};
  1. 定义 action 类型
// 定义 action 类型
type CartAction =
  | { type: 'ADD_ITEM'; payload: CartItem }
  | { type: 'REMOVE_ITEM'; payload: string }
  | { type: 'UPDATE_QUANTITY'; payload: { id: string; quantity: number } };
  1. 编写 reducer 函数
const cartReducer = (state: CartState, action: CartAction): CartState => {
  switch (action.type) {
    case 'ADD_ITEM':
      return {
      ...state,
        items: [...state.items, action.payload],
        totalPrice: state.totalPrice + action.payload.price * action.payload.quantity
      };
    case 'REMOVE_ITEM':
      const removedItem = state.items.find(item => item.id === action.payload);
      if (!removedItem) return state;
      return {
      ...state,
        items: state.items.filter(item => item.id!== action.payload),
        totalPrice: state.totalPrice - removedItem.price * removedItem.quantity
      };
    case 'UPDATE_QUANTITY':
      return state.items.map(item => {
        if (item.id === action.payload.id) {
          const priceDiff = (action.payload.quantity - item.quantity) * item.price;
          return {...item, quantity: action.payload.quantity };
        }
        return item;
      });
      return {
      ...state,
        totalPrice: state.totalPrice + priceDiff
      };
    default:
      return state;
  }
};
  1. 在组件中使用 useReducer
import React, { useReducer } from'react';

const Cart: React.FC = () => {
  const initialState: CartState = {
    items: [],
    totalPrice: 0
  };
  const [cart, dispatch] = useReducer(cartReducer, initialState);

  const addItem = (item: CartItem) => {
    dispatch({ type: 'ADD_ITEM', payload: item });
  };

  const removeItem = (id: string) => {
    dispatch({ type: 'REMOVE_ITEM', payload: id });
  };

  const updateQuantity = (id: string, quantity: number) => {
    dispatch({ type: 'UPDATE_QUANTITY', payload: { id, quantity } });
  };

  return (
    <div>
      {/* 购物车组件内容 */}
    </div>
  );
};

export default Cart;