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

React项目中state存储的提示消息无法正确渲染到浏览器问题求助

问题原因&修复方案

你遇到的两个核心问题(提示消息不渲染、偶现类型报错)由以下几个代码疏漏导致:

  • 初始state未提前声明badmsg、searchKeyword、searchUrl字段,状态更新逻辑不统一
  • 随机笑话下标计算错误:数组下标范围是0 ~ 数组长度-1,你当前的计算逻辑会生成等于数组长度的下标,读取不存在的数组项就会触发Cannot read properties of undefined (reading 'value')报错
  • 状态更新时注释了badmsg的赋值逻辑,提示消息根本没有存入state,页面自然渲染不出来
  • 没有对异步请求添加异常捕获逻辑,接口请求失败时就会触发未处理的Promise拒绝报错

修正后的完整代码

import { useState, useEffect } from 'react';
import axios from 'axios';
// 注意替换为你本地的Chuck图片实际导入路径
import Chuck from './chuck-img.png';

function App() {
  // 补充所有用到的字段到初始state
  const [state, setState] = useState({
    joke: '',
    badmsg: '',
    searchKeyword: '',
    searchUrl: 'https://api.chucknorris.io/jokes/search?query='
  });

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const result = await axios.get('https://api.chucknorris.io/jokes/random');
      setState({
        ...state,
        joke: result.data.value,
        badmsg: ''
      });
    } catch (err) {
      setState({
        ...state,
        badmsg: '获取随机笑话失败,请稍后重试'
      });
    }
  };

  const searchJoke = (ev) => {
    setState({ 
      ...state,
      searchKeyword: ev.target.value
    })
  }

  const fetchMyJoke = async () => {
    try {
      const result = await axios.get(state.searchUrl + state.searchKeyword);
      const resultList = result.data.result;
      let badmsg = '';
      let joke = '';

      if (resultList.length < 1) {
        badmsg = `没有找到和${state.searchKeyword}相关的笑话`;
      } else {
        // 修正随机下标计算逻辑,删除多余的+1
        const jokePos = Math.floor(Math.random() * resultList.length);
        joke = resultList[jokePos].value;
        badmsg = '请享用笑话:';
      }

      setState({
        ...state,
        joke,
        badmsg
      });
    } catch (err) {
      setState({
        ...state,
        badmsg: '搜索请求失败,请检查网络后重试'
      });
    }
  }

  return (
    <div className="container">
      <div className="row"> 
        <div className="col-6">   
            <h1 className="title">Chuck Norris API</h1>
            <img src={Chuck} height="70%" width="50%" alt="Chuck Norris force of one"/> 
          </div>

        <div className="col-4 searchJokeCol"> 
          <div className="card"> 
            <div className="card-header"> 
              搜索关键词
            </div>
              <div className="card-body">
                <input type="text" onChange={searchJoke} value={state.searchKeyword} />
              </div>
          </div>
          <div >
            <button onClick={fetchMyJoke} className="btn btn-warning btn-lg" >生成笑话</button>
          </div>
        </div>
      </div>
      <h2 className="subtitle"> 笑话来了!</h2>
      <h4>{state.badmsg} {state.joke} </h4>
    </div>
  );
}

export default App;

额外优化说明

补充了输入框的value双向绑定,避免受控组件变成非受控组件的潜在问题,所有异常场景的提示都会正常渲染到页面上,不会再出现未捕获的Promise报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:24:00