MST

星途 面试题库

面试题:React useEffect Hook在复杂状态管理中的应用

假设你正在开发一个电商购物车功能,在React中使用useEffect Hook来管理购物车状态。购物车状态包括商品列表、总价等。当商品数量变化或商品被移除时,总价需要实时更新。同时,当购物车状态发生变化时,需要将购物车数据存储到本地缓存中。请描述如何使用useEffect Hook实现这些功能,以及如何处理可能出现的性能问题。
22.0万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 使用useEffect实现功能
    • 状态定义: 在React组件中,首先定义购物车状态。例如:
import React, { useState, useEffect } from'react';

const ShoppingCart = () => {
    const [cartItems, setCartItems] = useState([]);
    const [totalPrice, setTotalPrice] = useState(0);
  • 计算总价并更新本地缓存useEffect可以依赖cartItems数组,每当cartItems变化时(商品数量变化或商品被移除),重新计算总价并更新本地缓存。
useEffect(() => {
    const newTotal = cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0);
    setTotalPrice(newTotal);
    localStorage.setItem('cartData', JSON.stringify({ cartItems, totalPrice: newTotal }));
}, [cartItems]);
  • 从本地缓存读取初始数据: 在组件挂载时,从本地缓存读取购物车数据并初始化状态。
useEffect(() => {
    const cartData = localStorage.getItem('cartData');
    if (cartData) {
        const { cartItems, totalPrice } = JSON.parse(cartData);
        setCartItems(cartItems);
        setTotalPrice(totalPrice);
    }
}, []);
  1. 处理性能问题
    • 减少不必要的渲染: 使用React.memo包裹子组件,避免子组件在不必要的时候重新渲染。例如,如果有一个显示购物车商品列表的子组件CartItemList
const CartItemList = React.memo(({ items }) => {
    return (
        <ul>
            {items.map(item => (
                <li key={item.id}>{item.name} - {item.quantity} x {item.price}</li>
            ))}
        </ul>
    );
});
  • 优化useEffect依赖: 确保useEffect的依赖数组精确,只包含真正影响副作用的变量。例如,如果某个useEffect中计算总价的逻辑只依赖cartItems,就不要在依赖数组中添加其他无关变量,避免不必要的副作用执行。
  • 节流与防抖: 如果商品数量变化是通过用户频繁操作(如点击增减按钮)触发的,可以使用节流或防抖技术。例如,使用lodash库的debounce函数来延迟计算总价和更新本地缓存的操作,避免短时间内多次不必要的计算和存储。
import { debounce } from 'lodash';

const calculateAndSave = debounce(() => {
    const newTotal = cartItems.reduce((acc, item) => acc + item.price * item.quantity, 0);
    setTotalPrice(newTotal);
    localStorage.setItem('cartData', JSON.stringify({ cartItems, totalPrice: newTotal }));
}, 300);

// 在商品数量变化或商品移除的事件处理函数中调用 calculateAndSave