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

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;

关键修复说明

  1. 状态类型修正:将listCollaborater初始化为空数组,从localStorage取数据后先解析并校验数组类型,保证length调用始终有效。
  2. Hooks规范遵守:把useSelector移到组件顶层,避免条件调用引发的状态问题。
  3. 服务调用优化:用useEffect包裹服务调用,控制执行时机,避免重复调用。
  4. 随机逻辑调整:将随机获取逻辑改为普通函数,点击触发操作,直接返回完整对象,同时处理数组为空的边界情况。
  5. 避免无限循环:调整useEffect的依赖数组,防止因状态更新导致重复执行赋值逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:00:38