React保存用户数据到localStorage报错TypeError: newData is not iterable怎么解决
错误根因
你遇到的TypeError: newData is not iterable错误来自App.js里的onSaveDataHandler函数:
- 你在
LoginForm的sendDataToChild方法里传给onSaveData的参数是单个用户对象,不是数组 - 你在更新
userData时对newData用了扩展运算符...newData,普通对象默认不能被迭代,同时你还把已经是数组的prevData直接放到新数组里,会导致userData变成二维数组,后续遍历也会报错。
修复方案
1. 修复App.js中的onSaveDataHandler
把原有代码:
const onSaveDataHandler = (newData) => { setUserData((prevData)=>{ return [prevData,...newData]; }); };
修改为:
const onSaveDataHandler = (newData) => { setUserData((prevData)=>{ // prevData已经是数组,直接把新的用户对象追加到数组末尾即可 return [...prevData, newData]; }); };
2. 修复localStorage重复覆盖的问题
你现在把localStorage.setItem('CompleteData',JSON.stringify(userData))直接写在组件顶层,每次组件渲染都会执行,会覆盖掉之前的存储值,应该放到useEffect里监听userData变化再更新,同时初始化时直接从localStorage读取历史数据:
// 修改userData初始化逻辑 const [userData,setUserData] = useState(()=>{ const saved = localStorage.getItem('CompleteData'); return saved ? JSON.parse(saved) : []; }); // 新增useEffect监听userData变化同步到localStorage useEffect(()=>{ localStorage.setItem('CompleteData',JSON.stringify(userData)); },[userData])
3. 修复LoginForm中的遍历逻辑错误
原来的onSubmitHandler里的element[i].username是错误写法,forEach的第一个参数已经是单条用户数据,不需要再加索引,优化为更简洁的查找逻辑:
const onSubmitHandler = (event) => { event.preventDefault(); const matchedUser = props.usersD.find(user => user.username === enteredUsername && user.password === enteredPassword ); if(matchedUser){ props.onLogin(matchedUser.username, matchedUser.firstname, matchedUser.lastname, matchedUser.password); setTrue(true); }else{ setTrue(false); } };
4. 修复SignUp显示判断的错误逻辑
原来的enteredUsername !== Object.keys(props.usersD).username是错误写法,Object.keys(props.usersD)返回的是键名数组,没有username属性,直接判断点击状态即可:
{isClicked ? ( <SignUp dataTransfer={sendDataToChild} clk={setIsClicked}/> ) : ( // 原有表单代码 )}
完成以上修改后报错就会消失,用户数据也可以正常存储和展示。
内容的提问来源于stack exchange,提问作者nitin bakaya
相关产品推荐
相关产品推荐

