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
相关产品推荐
相关产品推荐

