You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化React localStorage存储代码以实现DRY(避免重复)原则?

优化方案:遵循DRY原则重构你的React localStorage逻辑

嘿,我瞅了你的代码,确实有不少重复的localStorage操作逻辑,咱们一步步把它重构得更简洁、更易维护,完美贴合DRY原则~

核心重复点分析

你代码里的重复主要集中在这几块:

  • 两次重复的localStorage.getItem + JSON.parse操作(分别处理文本和URL)
  • 两次几乎一样的数组更新+存储逻辑(扩展运算符合并新值后存回localStorage)
  • 两处重复的列表渲染map逻辑

具体优化步骤

1. 抽象通用的localStorage工具函数

把重复的读取、更新逻辑封装成通用函数,这样不用每次都写重复的JSON解析和数组处理:

// 通用读取localStorage数组的函数
const getStoredArray = (storageKey) => {
  return JSON.parse(localStorage.getItem(storageKey) || "[]");
};

// 通用更新localStorage数组的函数
const updateStoredArray = (storageKey, newValue) => {
  const currentArray = getStoredArray(storageKey);
  const updatedArray = [...currentArray, newValue];
  localStorage.setItem(storageKey, JSON.stringify(updatedArray));
  return updatedArray;
};

2. 用状态缓存localStorage数据,避免重复读取

原代码每次渲染都会重新读取localStorage,咱们用React的useState初始化时加载数据,后续更新时同步状态,减少不必要的IO操作:

const [localStoredValues, setLocalStoredValues] = useState(() => getStoredArray("localValue"));
const [urlStoredValues, setUrlStoredValues] = useState(() => getStoredArray("URLValue"));

3. 简化按钮点击逻辑,复用工具函数

把原来重复的数组更新逻辑替换成调用通用函数,同时同步组件状态:

  • Save按钮逻辑:
const saveBtn = () => {
  const updatedLocalArray = updateStoredArray("localValue", leadValue.inputVal);
  setLocalStoredValues(updatedLocalArray);
  setMyLeads(prev => [...prev, leadValue.inputVal]);
  setDisplay(false);
};
  • Tab捕获按钮逻辑:
const tabBtn = () => {
  chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    const url = tabs[0].url;
    const updatedUrlArray = updateStoredArray("URLValue", url);
    setUrlStoredValues(updatedUrlArray);
    setMyLeads(prev => [...prev, url]);
  });
  setDisplay(false)
};

4. 合并重复的列表渲染逻辑

原来的displayLocalItems和displayTabUrls可以合并成一个数组后统一渲染,减少重复的JSX代码:

const displayAllStoredItems = [...localStoredValues, ...urlStoredValues].map(item => (
  <List key={item} val={item} />
));

5. 完善删除按钮的状态同步

清空localStorage后,别忘了同步重置组件内的状态:

const deleteBtn = () => {
  window.localStorage.clear();
  setMyLeads([]);
  setLocalStoredValues([]);
  setUrlStoredValues([]);
};

完整优化后的代码

/*global chrome*/
import { useState } from 'react';
import List from './components/List'
import { SaveBtn, DeleteBtn, DisplayBtn, TabBtn} from "./components/Buttons"

// 通用localStorage操作工具函数
const getStoredArray = (storageKey) => {
  return JSON.parse(localStorage.getItem(storageKey) || "[]");
};

const updateStoredArray = (storageKey, newValue) => {
  const currentArray = getStoredArray(storageKey);
  const updatedArray = [...currentArray, newValue];
  localStorage.setItem(storageKey, JSON.stringify(updatedArray));
  return updatedArray;
};

function App() {
  const [myLeads, setMyLeads] = useState([]);
  const [leadValue, setLeadValue] = useState({
    inputVal: "",
  });
  const [display, setDisplay] = useState(false);

  // 用状态缓存localStorage数据
  const [localStoredValues, setLocalStoredValues] = useState(() => getStoredArray("localValue"));
  const [urlStoredValues, setUrlStoredValues] = useState(() => getStoredArray("URLValue"));

  const tabBtn = () => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      const url = tabs[0].url;
      const updatedUrlArray = updateStoredArray("URLValue", url);
      setUrlStoredValues(updatedUrlArray);
      setMyLeads(prev => [...prev, url]);
    });
    setDisplay(false)
  };

  const handleChange = (event) => {
    const { name, value } = event.target;
    setLeadValue((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const saveBtn = () => {
    const updatedLocalArray = updateStoredArray("localValue", leadValue.inputVal);
    setLocalStoredValues(updatedLocalArray);
    setMyLeads(prev => [...prev, leadValue.inputVal]);
    setDisplay(false);
  };

  const displayBtn = () => {
    setDisplay(true);
  };

  const deleteBtn = () => {
    window.localStorage.clear();
    setMyLeads([]);
    setLocalStoredValues([]);
    setUrlStoredValues([]);
  };

  const listItem = myLeads.map((led) => (
    <List key={led} val={led} />
  ));

  // 合并后的存储项渲染逻辑
  const displayAllStoredItems = [...localStoredValues, ...urlStoredValues].map(item => (
    <List key={item} val={item} />
  ));

  return (
    <main>
      <input 
        name="inputVal" 
        value={leadValue.inputVal} 
        type="text" 
        onChange={handleChange} 
        required 
      />
      <SaveBtn saveBtn={saveBtn} />
      <TabBtn tabBtn={tabBtn} />
      <DisplayBtn displayBtn={displayBtn} />
      <DeleteBtn deleteBtn={deleteBtn} />
      <ul>{listItem}</ul>
      {display && (
        <ul>
          {displayAllStoredItems}
        </ul>
      )}
    </main>
  );
}

export default App;

额外优化建议(可选)

如果后续不需要区分手动输入和Tab捕获的内容,可以把两个localStorage键合并成一个(比如allLeads),这样能进一步减少逻辑复杂度,不过这取决于你的业务需求~

内容的提问来源于stack exchange,提问作者user3574939

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:57:28