数据持久化存储Hook实战方案

HeavyEar +0/-0 0 0 正常 2025-12-24T07:01:19 React Hooks · 状态管理 · 持久化存储

在复杂的React应用中,数据持久化存储是一个常见且重要的需求。本文将分享一个实际的Hook重构方案,解决跨组件状态同步和本地存储的问题。

场景分析

假设我们有一个电商应用,需要在用户浏览商品时保存搜索历史、购物车数据,并在页面刷新后保持这些状态。传统的做法是使用localStorage配合useEffect,但容易出现状态不一致和性能问题。

核心Hook实现

import { useState, useEffect, useCallback } from 'react';

const usePersistentState = (key, initialValue) => {
  // 从localStorage初始化状态
  const [state, setState] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(`Failed to load ${key} from localStorage`, error);
      return initialValue;
    }
  });

  // 持久化到localStorage
  useEffect(() => {
    try {
      window.localStorage.setItem(key, JSON.stringify(state));
    } catch (error) {
      console.error(`Failed to save ${key} to localStorage`, error);
    }
  }, [key, state]);

  return [state, setState];
};

实际应用重构

将购物车和搜索历史整合到一个复合Hook中:

const useUserPersistence = () => {
  const [cart, setCart] = usePersistentState('shopping_cart', []);
  const [searchHistory, setSearchHistory] = usePersistentState('search_history', []);
  
  const addToCart = useCallback((item) => {
    setCart(prev => {
      const existing = prev.find(cartItem => cartItem.id === item.id);
      if (existing) {
        return prev.map(cartItem =>
          cartItem.id === item.id
            ? { ...cartItem, quantity: cartItem.quantity + 1 }
            : cartItem
        );
      }
      return [...prev, { ...item, quantity: 1 }];
    });
  }, []);

  const updateSearchHistory = useCallback((query) => {
    setSearchHistory(prev => {
      const filtered = prev.filter(item => item !== query);
      return [query, ...filtered.slice(0, 9)]; // 保留最近10条记录
    });
  }, []);

  return {
    cart,
    searchHistory,
    addToCart,
    updateSearchHistory
  };
};

性能优化策略

  1. 使用useCallback避免不必要的重渲染
  2. 实现防抖机制处理高频更新
  3. 添加错误边界处理localStorage异常
  4. 对大数据量进行分片存储

通过这种Hook重构方案,我们实现了状态的自动持久化,同时保持了良好的性能和可维护性。

推广
广告位招租

讨论

0/2000