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

React项目点击刷新切换问题时偶现页面崩溃空白,求技术排查

React项目刷新按钮偶尔崩溃问题修复

问题描述

开发一个React项目,功能为展示单个问题,点击刷新按钮切换问题内容。整体运行正常,但点击刷新按钮时偶尔会出现代码崩溃、页面空白的情况。

相关代码

import React from "react"
import questionsData from '../questionsData.js'

function Content(){

    const [question, setQuestion] = React.useState({
        heading:"",
        hints : []
    })

    const [refresh, setRefresh] = React.useState(0)
    

    React.useEffect(function(){
        if(questionsData){
            const randomNo = Math.floor(Math.random() * questionsData.length) + 1
        
            let headinggg = questionsData[randomNo].heading
            let hintsss = questionsData[randomNo].hints
            setQuestion({
              heading: headinggg,
              hints: hintsss
            })
        }else{
           document.write("loading")
        }
        
         
    },[refresh])

  const sugg = question.hints.map((hint) => {
      return(
          <li>{hint}</li>
      )
  })

  function renderQuestion(){
        setRefresh(refresh + 1)
  }

    return(
            <div className="content">
                <div className="question">
                        <h4>{question.heading}</h4>
                        <br />
                        <span>You should say:</span> 
                        <ul>
                           {sugg} 
                        </ul>
                    </div>
                <div className="action">
                    <div className="record">
                        <img src="images/211859_mic_icon.svg" alt="" />
                    </div>
                    <div className="refresh" onClick={renderQuestion}>
                        <img src="images/3994399_refresh_reload_repeat_rotate_sync_icon.svg" alt="" />
                    </div>
                </div>
            </div>
    ) 
}

export default Content

错误截图

问题截图1
问题截图2

问题原因

崩溃核心原因是数组索引越界:
代码中随机数生成逻辑const randomNo = Math.floor(Math.random() * questionsData.length) + 1存在错误。数组索引从0开始,Math.random() * questionsData.length的取值范围是[0, questionsData.length),经Math.floor处理后最大值为questionsData.length - 1,再加1会得到questionsData.length,此时访问questionsData[randomNo]会返回undefined,后续读取heading和hints时会抛出错误,导致组件渲染失败、页面空白。

另外,document.write("loading")属于React不规范用法,会覆盖整个文档,也可能引发异常,建议用React状态管理加载状态替代。

修复方案

  1. 修正随机数生成逻辑:去掉多余的+1,确保索引在合法范围内
const randomNo = Math.floor(Math.random() * questionsData.length)
  1. 替换document.write为状态管理加载状态(可选优化)
// 添加加载状态
const [isLoading, setIsLoading] = React.useState(true)

React.useEffect(function(){
    if(questionsData){
        const randomNo = Math.floor(Math.random() * questionsData.length)
        const selectedQuestion = questionsData[randomNo] || { heading: "", hints: [] }
        setQuestion(selectedQuestion)
        setIsLoading(false)
    }else{
        setIsLoading(true)
    }
},[refresh])

// 渲染时判断加载状态
if(isLoading) return <div>loading</div>
  1. 添加空值保护(可选):避免选中undefined时出错
const selectedQuestion = questionsData[randomNo] || { heading: "", hints: [] }
setQuestion(selectedQuestion)

修复后的完整代码示例:

import React from "react"
import questionsData from '../questionsData.js'

function Content(){

    const [question, setQuestion] = React.useState({
        heading:"",
        hints : []
    })
    const [refresh, setRefresh] = React.useState(0)
    const [isLoading, setIsLoading] = React.useState(true)

    React.useEffect(function(){
        if(questionsData && questionsData.length > 0){
            const randomNo = Math.floor(Math.random() * questionsData.length)
            const selectedQuestion = questionsData[randomNo] || { heading: "", hints: [] }
            setQuestion(selectedQuestion)
            setIsLoading(false)
        }else{
            setIsLoading(true)
        }
    },[refresh])

    const sugg = question.hints.map((hint, index) => {
        return <li key={index}>{hint}</li>
    })

    function renderQuestion(){
        setRefresh(prev => prev + 1)
    }

    if(isLoading) return <div>loading</div>

    return(
            <div className="content">
                <div className="question">
                        <h4>{question.heading}</h4>
                        <br />
                        <span>You should say:</span> 
                        <ul>
                           {sugg} 
                        </ul>
                    </div>
                <div className="action">
                    <div className="record">
                        <img src="images/211859_mic_icon.svg" alt="麦克风图标" />
                    </div>
                    <div className="refresh" onClick={renderQuestion}>
                        <img src="images/3994399_refresh_reload_repeat_rotate_sync_icon.svg" alt="刷新图标" />
                    </div>
                </div>
            </div>
    ) 
}

export default Content

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:10:14