React组件中state数组首个值为undefined的问题排查
React组件问题分析与解决
问题1:componentDidMount中处理数组出现undefined报错
你在componentDidMount里调用get()后立刻执行循环处理数组,出现首个值undefined并报错的原因是:
fetch是异步操作,调用get()后不会等待接口返回结果,会直接执行后续循环代码- 此时组件的
state.arrayJson还是初始值[""],循环i从0到3时,i=1对应的arrayJson[1]不存在,值为undefined,访问header[j]就会触发报错
问题2:render中两次打印数组的原因
控制台先输出初始的[""],再输出接口返回的数组,是因为React组件的渲染流程:
- 组件初始化时,会先执行一次
render,此时state是构造函数里设置的初始值[""],所以打印第一次 componentDidMount调用get()后,fetch请求完成并调用setState更新arrayJson,这会触发组件重新渲染,render再次执行,此时state已经是接口返回的数组,所以打印第二次
解决方案
要确保在接口数据返回并更新state后再处理数组,有两种常用方式:
方式1:在setState的回调中处理数组
setState支持第二个回调参数,会在state更新完成、组件重新渲染后执行:
import React, {Component} from "react" import './index.css'; export default class ListArticle extends Component { constructor(props) { super(props); this.state = { arrayJson: [""], } } get() { fetch("http://localhost:8080/getHeaders", { method: "GET" }) .then(data=>data.json()) .then((data)=>{ // setState回调中处理更新后的state this.setState({arrayJson: data.headerArray}, () => { this.processHeaders(); }) }) } // 抽离处理逻辑到单独方法 processHeaders() { this.state.arrayJson.forEach(header => { if (!header) return; // 跳过空值或undefined const processedText = header.length > 120 ? header.slice(0, 120) + "..." : header; console.log(processedText); }); } componentDidMount() { this.get(); } render() { return ( <div id={"container"}></div> ); } }
方式2:使用async/await等待异步请求完成
将get方法改为异步函数,在componentDidMount中等待请求完成后处理数组:
import React, {Component} from "react" import './index.css'; export default class ListArticle extends Component { constructor(props) { super(props); this.state = { arrayJson: [""], } } async get() { const response = await fetch("http://localhost:8080/getHeaders", {method: "GET"}); const data = await response.json(); this.setState({arrayJson: data.headerArray}); this.processHeaders(); } processHeaders() { this.state.arrayJson.forEach(header => { if (!header) return; const processedText = header.length > 120 ? header.slice(0, 120) + "..." : header; console.log(processedText); }); } async componentDidMount() { await this.get(); } render() { return ( <div id={"container"}></div> ); } }
额外优化点
- 不要固定循环4次,改用
arrayJson.length遍历,避免数组长度不足时出现越界问题 - 增加空值判断,跳过
undefined或空字符串,避免报错
内容的提问来源于stack exchange,提问作者артур хасанов
相关产品推荐
相关产品推荐

