React动物投票应用如何将投票状态存到localStorage实现刷新后数据不丢失
实现方案
你可以通过两种主流方案实现刷新保留投票数据,根据你的使用场景选择即可:
方案1:前端本地存储(单用户本地使用,无需后端改动)
直接用浏览器自带的localStorage存储投票数据,实现成本最低:
- 组件初始化时从
localStorage读取已保存的投票数据作为state初始值 - 每次投票更新state后,自动将最新数据同步到
localStorage
修改后的组件代码如下:
import {fetchAll} from '../AppFetch'; import {useEffect, useState} from 'react'; export default function Animals() { useEffect(( ) => { fetchAll("http://localhost:3000/animals.json", setData) }, []); const [data, setData] = useState({}); // 初始化时从localStorage读数据,没有就用空对象 const [state, setState] = useState(() => { const savedVotes = localStorage.getItem('animalVotes'); return savedVotes ? JSON.parse(savedVotes) : {}; }); // 监听state变化,每次更新自动存到localStorage useEffect(() => { localStorage.setItem('animalVotes', JSON.stringify(state)); }, [state]); const upVote = ({ target: { name } }) => { setState({ ...state, [name]: (state[name] || 0) + 1 }); }; const downVote = ({target:{name}}) => { // 加了Math.max避免票数变负,不需要可以直接删掉保留原有逻辑 setState({...state, [name]: Math.max((state[name] || 0) - 1, 0)}) } const animalsArr = []; const airArr = []; for(let i=0; i<Object.entries(data).length; i++){ const areas = Object.values(data)[i]; for(let j=0; j < Object.keys(areas).length; j++){ const animal=Object.entries(areas)[1][1] const air=Object.entries(areas)[0][1] animalsArr.push(animal[j]); airArr.push(air[j]); } } return <div className="row"> <div className="land"> {animalsArr.map(({ name }) => ( <div key={name}> <button className="f" name={name} onClick={upVote}> 🢁 </button> <p>{name} - {state[name] || 0}</p> <button className="s" name={name} onClick={downVote}> 🢃 </button> </div> ))} </div> <div className="air"> {airArr.map(({ name }) => ( <div key={name}> <button className="f" name={name} onClick={upVote}> 🢁 </button> <p>{name} - {state[name] || 0}</p> <button className="s" name={name} onClick={downVote}> 🢃 </button> </div> ))} </div> </div>; }
注:该方案的数据仅保存在当前用户的当前浏览器中,清理浏览器缓存会丢失数据,也无法实现多用户共享投票数据
方案2:后端持久化(多用户共享投票数据)
你现在用的animals.json是静态文件,无法直接通过前端修改,需要后端支持:
- 快速测试可直接用
json-server工具,一行命令启动animals.json为支持增删改查的REST接口,无需手动写后端代码 - 正式场景可自行搭建后端服务(比如Node.js+Express、Java等),提供两个核心接口:
- 拉取全量动物投票数据接口
- 提交投票更新接口
- 每次用户点击投票按钮时,除了更新本地state,还要发请求调用后端更新接口,修改服务端存储的投票数据(可存在json文件或者数据库中)
- 组件初始化时直接从后端拉取最新的投票数据,不需要依赖本地存储
内容的提问来源于stack exchange,提问作者Egon Adelsberger
相关产品推荐
相关产品推荐

