React Todo本地存储报错:map函数无效、键值警告及动态颜色需求求助
问题1:fetchdata.map is not a function 报错
- 原因:
localStorage.getItem('state')返回的是JSON字符串(或null),直接赋值会导致fetchdata不是数组,无法调用map;另外直接在组件顶层调用setFetchData会触发无限重渲染。 - 解决:用
useEffect在组件挂载时读取localStorage,通过JSON.parse解析字符串,同时处理空数据的默认情况(返回空数组)。
问题2:设置key仍提示“需唯一键值”
- 原因:用todo文本作为key,当存在重复内容的todo时,key会重复,React要求key必须全局唯一。
- 解决:给每个todo项添加唯一标识(如
id),用id作为key。简单场景下可以用Date.now()生成id,复杂场景可使用uuid库生成更可靠的唯一值。
问题3:添加列表项动态颜色效果
- 解决:编写随机十六进制颜色生成函数,渲染每个todo项时调用该函数,或预设一组颜色循环使用。
修正后的完整代码
import React, { useState, useEffect } from 'react'; import './style.css'; // 生成随机十六进制颜色 const getRandomColor = () => { const hexChars = '0123456789ABCDEF'; let color = '#'; for (let i = 0; i < 6; i++) { color += hexChars[Math.floor(Math.random() * 16)]; } return color; }; export default function App() { // 改用对象数组存储todo,每个项包含唯一id和文本内容 const [todos, setTodos] = useState([]); const [inputData, setInputData] = useState(''); // 组件挂载时从localStorage加载已有todo useEffect(() => { const savedTodos = localStorage.getItem('todos'); if (savedTodos) { setTodos(JSON.parse(savedTodos)); } }, []); // todo列表变化时,同步更新到localStorage useEffect(() => { localStorage.setItem('todos', JSON.stringify(todos)); }, [todos]); const addHandler = () => { if (!inputData.trim()) return; // 过滤空输入 setTodos(prevTodos => [ ...prevTodos, { id: Date.now(), text: inputData.trim() } ]); setInputData(''); }; return ( <div> <input onChange={(e) => setInputData(e.target.value)} value={inputData} placeholder="add items" /> <button onClick={addHandler}>Add</button> {/* 修复HTML语义:li必须包裹在ul/ol中 */} <ul> {todos.map((item) => ( <li key={item.id} style={{ color: getRandomColor() }} > {item.text} </li> ))} </ul> </div> ); }
内容的提问来源于stack exchange,提问作者AXak
相关产品推荐
相关产品推荐

