MST

星途 面试题库

面试题:React组件状态管理与生命周期在复杂业务场景下的协调

假设你正在开发一个电商购物车功能,购物车组件需要实时响应商品数量变化、总价计算以及库存状态更新。描述你将如何利用React的生命周期方法和状态管理机制来实现这个功能,包括如何处理性能优化问题。
33.5万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 状态管理
    • 在React组件的state中定义购物车商品列表,每个商品对象包含商品ID、名称、价格、数量、库存等信息。例如:
    constructor(props) {
        super(props);
        this.state = {
            cartItems: [
                { id: 1, name: '商品1', price: 10, quantity: 1, stock: 10 },
                // 其他商品...
            ]
        };
    }
    
  2. 商品数量变化处理
    • 增加/减少数量
      • 创建处理函数,如handleQuantityChange,该函数接收商品ID和变化的数量(增加为正数,减少为负数)作为参数。
      • 使用setState更新cartItems中对应商品的数量。例如:
    handleQuantityChange = (itemId, change) => {
        this.setState((prevState) => {
            const newCartItems = prevState.cartItems.map(item => {
                if (item.id === itemId) {
                    return {
                       ...item,
                        quantity: item.quantity + change
                    };
                }
                return item;
            });
            return {
                cartItems: newCartItems
            };
        });
    };
    
  3. 总价计算
    • 计算逻辑
      • 在组件中定义一个计算总价的方法,如calculateTotalPrice
      • 遍历cartItems,将每个商品的价格乘以数量并累加。例如:
    calculateTotalPrice = () => {
        return this.state.cartItems.reduce((total, item) => {
            return total + item.price * item.quantity;
        }, 0);
    };
    
    • 更新视图
      • 可以在render方法中调用calculateTotalPrice获取总价并展示。例如:
    render() {
        const totalPrice = this.calculateTotalPrice();
        return (
            <div>
                {/* 购物车其他内容 */}
                <p>总价: {totalPrice}</p>
            </div>
        );
    }
    
  4. 库存状态更新
    • 库存检查
      • handleQuantityChange函数中,当更新商品数量时,检查新的数量是否超过库存。如果超过库存,阻止数量增加,并给出提示。例如:
    handleQuantityChange = (itemId, change) => {
        this.setState((prevState) => {
            const newCartItems = prevState.cartItems.map(item => {
                if (item.id === itemId) {
                    if (change > 0 && item.quantity + change > item.stock) {
                        // 给出库存不足提示,这里可以用弹窗等方式,此处简单console.log
                        console.log('库存不足');
                        return item;
                    }
                    return {
                       ...item,
                        quantity: item.quantity + change
                    };
                }
                return item;
            });
            return {
                cartItems: newCartItems
            };
        });
    };
    
    • 库存更新
      • 如果商品数量减少,可以通过API调用(假设后端提供更新库存的接口)更新库存。可以在componentDidUpdate生命周期方法中处理,当cartItems变化且商品数量减少时,发送更新库存的请求。例如:
    componentDidUpdate(prevProps, prevState) {
        if (prevState.cartItems!== this.state.cartItems) {
            const changedItems = this.state.cartItems.filter((item, index) => {
                return item.quantity!== prevState.cartItems[index].quantity;
            });
            changedItems.forEach(item => {
                if (item.quantity < prevState.cartItems.find(i => i.id === item.id).quantity) {
                    // 发送API请求更新库存,这里假设API函数为updateStock
                    updateStock(item.id, item.stock + (prevState.cartItems.find(i => i.id === item.id).quantity - item.quantity));
                }
            });
        }
    }
    
  5. 性能优化
    • 使用shouldComponentUpdate
      • 根据组件的业务逻辑,判断是否需要更新。例如,只有当cartItems发生变化时才更新组件,而不是每次状态变化都更新。
    shouldComponentUpdate(nextProps, nextState) {
        return nextState.cartItems!== this.state.cartItems;
    }
    
    • Memoization
      • 对于calculateTotalPrice这种纯函数,可以使用React.memo(如果是函数组件)或类似的记忆化技术(如lodashmemoize)来避免重复计算。如果是类组件,可以在类的构造函数中初始化一个变量来存储上次计算的总价,在calculateTotalPrice中先检查cartItems是否变化,如果未变化则返回缓存的总价。
    • 虚拟DOM优化
      • React自身的虚拟DOM机制会尽量减少真实DOM的更新。合理组织组件结构,避免不必要的嵌套,确保只有相关部分的DOM被更新。例如,将购物车商品列表单独封装成一个组件,这样当单个商品数量变化时,只更新该商品对应的DOM,而不是整个购物车的DOM。