React渲染时调用map报Cannot read properties of undefined错误如何解决
报错原因
- 初始state结构不匹配:你在constructor中初始化
data为空数组[],但接口返回的parsedData是包含list属性的对象。组件首次渲染时,this.state.data.list为undefined,调用map方法直接触发报错。 - setState异步更新特性:
setState是异步执行的,你在showData中setState后立刻读取this.state.data,理论上拿到的还是更新前的旧值,你当前测试能执行成功属于巧合,实际生产环境大概率会出现同render阶段一样的报错。 - 额外小问题:input的
value绑定写错了,你state中存储输入值的字段是word,但你绑定了this.state.value,会导致输入框无法正常输入内容。
解决步骤
- 修正初始state的结构,将
data初始化为包含list空数组的对象,保证首次渲染时data.list是可调用map的数组类型:
this.state = { word: "", data: { list: [] }, };
- 在render阶段调用map前添加可选链校验,避免极端情况下数据结构异常导致的报错:
{this.state.data?.list?.map((e) => { return <h1 key={e.definition}>{e.definition}</h1>; })}
注意:map渲染列表时必须给每个子元素添加唯一key属性,避免React渲染异常。
3. 修正input的value绑定:
<input type="text" value={this.state.word} onChange={this.handelWordChange} />
- 如果需要在
setState后立刻操作更新后的state,建议把逻辑放到setState的回调函数中,确保拿到的是最新值:
this.setState({ data: parsedData }, () => { this.state.data.list.map((e) => { console.log(e.definition); }); });
修正后完整代码
export class App extends Component { constructor(props) { super(props); this.state = { word: "", data: { list: [] }, }; } handelWordChange = (e) => { this.setState({ word: e.target.value }); }; showData = async () => { let url = `https://api.urbandictionary.com/v0/define?term=${this.state.word}`; let rawData = await fetch(url); let parsedData = await rawData.json(); this.setState({ data: parsedData }, () => { this.state.data.list.map((e) => { console.log(e.definition); }); }); }; render() { return ( <div> <input type="text" value={this.state.word} onChange={this.handelWordChange} /> <button onClick={this.showData}>Show</button> {this.state.data?.list?.map((e) => { return <h1 key={e.definition}>{e.definition}</h1>; })} </div> ); } }
内容的提问来源于stack exchange,提问作者Karan Sharma
相关产品推荐
相关产品推荐

