React点击获取随机对象遇NaN报错,请求技术协助
问题排查与解决:随机获取数组对象时出现NaN错误
错误原因分析
- 数组状态的类型与初始化错误:
listCollaborater初始设为空字符串,后续从localStorage取到的也是未解析的字符串(或null),导致test1.length要么是字符串的字符长度,要么在localStorage无数据时因test1为null直接报错,最终计算出NaN。 - Hooks使用违反规则:
useSelector被放在条件判断里调用,违反React Hooks必须在组件顶层执行的规范,会导致状态异常。 - 服务调用位置错误:
getListCollaboratorService(dispatch)直接写在组件顶层,每次渲染都会重复调用,造成资源浪费。 - 组件返回值不符合要求:
RandomCollaborater组件返回的是数字索引,不是React可渲染的元素,既不符合组件规范,也没实现“获取随机对象”的需求。
修复后的完整代码
import { useState, useEffect, useDispatch, useSelector } from 'react'; const AccountComponent = () => { const dispatch = useDispatch(); const [errorListCollaborater, setErrorListCollaborater] = useState(null); // 初始化为空数组,确保类型正确 const [listCollaborater, setListCollaborater] = useState([]); const storageUserDetails = localStorage.getItem("userDetails"); const userDetails = JSON.parse(storageUserDetails); // 把useSelector移到顶层,遵守Hooks规则 const storeStateCollaborater = useSelector(state => state.reducerListCollaborater.state); // 单独处理数据逻辑,避免条件调用Hooks const targetCollaboraterList = userDetails ? userDetails : storeStateCollaborater; // 服务调用放在useEffect里,仅挂载时执行一次 useEffect(() => { getListCollaboratorService(dispatch); }, [dispatch]); // 从localStorage加载并解析数组,处理异常情况 useEffect(() => { const savedList = localStorage.getItem("listCollaborater"); if (savedList) { try { const parsedList = JSON.parse(savedList); // 确保解析结果是数组,否则设为空数组 setListCollaborater(Array.isArray(parsedList) ? parsedList : []); } catch (e) { setErrorListCollaborater("协作列表解析失败"); setListCollaborater([]); } } }, []); // 依赖为空,避免无限循环 // 写普通函数获取随机对象,无需封装成组件 const getRandomCollaborater = () => { if (listCollaborater.length === 0) return null; const randomIndex = Math.floor(Math.random() * listCollaborater.length); return listCollaborater[randomIndex]; }; // 点击按钮触发随机获取操作 const handleRandomClick = () => { const randomItem = getRandomCollaborater(); console.log(randomItem); // 这里可以添加获取到对象后的后续逻辑,比如更新状态渲染到页面 }; return ( <div> <button onClick={handleRandomClick}>获取随机协作对象</button> {/* 示例:渲染获取到的随机对象 */} {getRandomCollaborater() && ( <div> <p>随机对象:{getRandomCollaborater().firstname} {getRandomCollaborater().lastname}</p> </div> )} </div> ); }; export default AccountComponent;
关键修复说明
- 状态类型修正:将
listCollaborater初始化为空数组,从localStorage取数据后先解析并校验数组类型,保证length调用始终有效。 - Hooks规范遵守:把
useSelector移到组件顶层,避免条件调用引发的状态问题。 - 服务调用优化:用
useEffect包裹服务调用,控制执行时机,避免重复调用。 - 随机逻辑调整:将随机获取逻辑改为普通函数,点击触发操作,直接返回完整对象,同时处理数组为空的边界情况。
- 避免无限循环:调整
useEffect的依赖数组,防止因状态更新导致重复执行赋值逻辑。
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

