React render返回值中能否将函数传给另一函数?遇'map of undefined'报错
核心错误根源
1. 异步执行逻辑认知偏差
调用嵌套函数的同步执行顺序,仅适用于所有任务为同步阻塞模式的场景,代码中存在两个关键认知偏差:
- axios发起的网络请求是异步非阻塞任务:
downloadJSON函数执行时,只是把网络请求任务推到异步任务队列,本身没有任何同步返回值,执行完直接返回undefined。主线程不会等待网络请求返回响应,会立刻继续执行外层的JSONToHTML方法,此时传入的参数就是undefined,直接触发map读取报错 - 在
.then回调里写的return res,只是把响应值传给Promise链的下一个回调,根本不会作为downloadJSON函数的返回值向外传递;哪怕手动把axios.get的Promise实例return出去,传给JSONToHTML的也是Promise对象,不是实际的JSON数组,Promise本身也没有map方法,同样会触发报错。
2. 数据渲染逻辑的其他错误
- 普通JS类不能直接作为React可渲染的内容,在
map里直接返回Line类本身,哪怕拿到了数组也无法正常渲染 - 在普通类的构造函数里直接写JSX是不合法的,构造方法不属于React的渲染流程,根本无法解析这类语法
正确实现方式
- 组件初始化时通过state定义默认值,给待渲染的JSON数组设置空数组默认值,从根源避免
map读取undefined的报错 - 在组件生命周期钩子里发起异步网络请求,等请求成功拿到响应后,调用
setState更新存储的数据,触发组件重新渲染 - 把展示逻辑拆成合法的React函数/类组件,渲染时遍历state存储的数组,将每条数据作为组件props传入
参考实现代码
import React from 'react'; import axios from 'axios'; // 合法的React展示组件 const Line = (props) => { return <p>{props.name}'s ID is {props.id}.</p> } class Viewer extends React.Component { constructor(props) { super(props); this.state = { jsonList: [] // 给数组设置默认空值,避免map报错 } } // 组件挂载完成后发起异步请求 componentDidMount() { const url = 'http://127.0.0.1:5000/sample_data'; axios.get(url).then(res => { // 请求成功后更新state触发重渲染 this.setState({ jsonList: res.data }) }) } render() { return ( <div> {this.state.jsonList.map(item => ( <Line key={item.id} id={item.id} name={item.name} /> ))} <p>OK</p> </div> ) } } export default Viewer
内容的提问来源于stack exchange,提问作者Staxks
相关产品推荐
相关产品推荐

