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

React+Vite项目刷新页面后已访问国家列表消失求助

解决React+Vite中localStorage持久化国家列表的问题

问题说明

使用React + Vite开发记录已访问国家的站点,期望页面刷新后已添加的国家列表不会丢失,但当前代码无法实现该localStorage持久化效果。

问题分析

当前代码的核心读写localStorage逻辑本身合理,但存在两个关键问题导致持久化失效:

  • 添加区域的「Cancelar」按钮错误绑定了删除列表项的函数,点击后会意外修改countries数组,导致localStorage存储异常数据
  • 组件初始化时通过useEffect读取localStorage,不如直接在useState初始化时读取更可靠,易出现初始渲染空列表的状态

修复后的完整代码

import React, { useState, useEffect } from 'react';
import './App.css';

function App() {
  // 初始化时直接从localStorage读取数据,替代后续useEffect读取
  const [countries, setCountries] = useState(() => {
    const stored = localStorage.getItem('countries');
    return stored ? JSON.parse(stored) : [];
  });
  const [newCountry, setNewCountry] = useState('');
  const [newDate, setNewDate] = useState('');

  // 监听countries变化,同步到localStorage
  useEffect(() => {
    localStorage.setItem('countries', JSON.stringify(countries));
  }, [countries]);

  const handleCountryChange = (e) => {
    setNewCountry(e.target.value);
  };

  const handleDateChange = (e) => {
    setNewDate(e.target.value);
  };

  const handleAdd = () => {
    if (newCountry && newDate) {
      const newCountryObj = { country: newCountry, date: newDate };
      setCountries((prevCountries) => [...prevCountries, newCountryObj]);
      setNewCountry('');
      setNewDate('');
    }
  };

  // 新增清空输入框的函数,替换原错误绑定
  const handleClearInput = () => {
    setNewCountry('');
    setNewDate('');
  };

  const handleEdit = (index) => {
    const updatedCountries = [...countries];
    const editedCountry = updatedCountries[index];
    const newCountryName = prompt(
      'Enter the new country name:',
      editedCountry.country
    );
    if (newCountryName) {
      editedCountry.country = newCountryName;
      setCountries(updatedCountries);
    }
  };

  const handleDelete = (index) => {
    const updatedCountries = [...countries];
    updatedCountries.splice(index, 1);
    setCountries(updatedCountries);
  };

  return (
    <div className="container">
      <div className="card">
        {/* Form card */}
        <div className="form-group">
          <label htmlFor="countryInput">País:</label>
          <input
            type="text"
            id="countryInput"
            value={newCountry}
            onChange={handleCountryChange}
            className="form-control"
          />
        </div>
        <div className="form-group">
          <label htmlFor="dateInput">Data:</label>
          <input
            type="date"
            id="dateInput"
            value={newDate}
            onChange={handleDateChange}
            className="form-control"
          />
        </div>
        <div className="button-group">
          <button onClick={handleAdd} className="btn btn-green">
            Adicionar
          </button>
          {/* 绑定正确的清空输入函数 */}
          <button onClick={handleClearInput} className="btn btn-red">
            Cancelar
          </button>
        </div>
      </div>

      {/* Countries card */}
      {countries.length > 0 && (
        <div className="card">
          {countries.map((country, index) => (
            <div key={index} className="country-item">
              <div className="country-info">
                <span>{country.country}</span>
                <span>{country.date}</span>
              </div>
              <div className="country-actions">
                <button
                  onClick={() => handleEdit(index)}
                  className="btn btn-edit"
                >
                  Editar
                </button>
                {/* 绑定删除函数,避免命名混淆 */}
                <button
                  onClick={() => handleDelete(index)}
                  className="btn btn-red"
                >
                  Apagar
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default App;

关键修复点

  • 初始化优化:将useState的初始值改为函数,直接从localStorage读取数据,确保组件渲染时就加载已存储的列表
  • 按钮绑定修正:新增handleClearInput函数负责清空输入框,替换原错误绑定的删除函数,避免误操作修改列表
  • 函数命名规范:将原handleCancel改为handleDelete,明确其删除列表项的功能,避免命名混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:45:12