react-ajax:组件接收到数据后,在render函数内return jsx模板:渲染数据列表,会出现报错,页面无法显示
原因:组件还没有render因为ajax是异步的而render第一次更新获取不到数据。
AJAX通常是一个异步请求,也就是说,即使componentDidMount函数调用完毕,数据也不会马上就获得,浏览器会在数据完全到达后才调用AJAX中所设定的回调函数,有时间差。因此当响应数据、更新state前,需要先通过this.isMounted() 来检测组件的状态是否已经mounted。
解决:
在jsx内加入判断,在满足条件的情况下渲染即可
{test instanceof Array?'数组':"不是数组"}
{ test instanceof Array ? ( <div> { test.map((v,i)=>{ return( <div key={i}>{v.name}</div> ) }) } </div>) : ( <div> </div> ) }
错误代码:
{/* { test.map((v,i)=>{ return( <div key={i}>{v.name}</div> ) }) } 不带判断报错信息: Cannot read property 'map' of null */}
注意不要这样判断:
test.length>0或test.length 页面都无发正常显示并报错
改成在jsx内这样判断: test instanceof Array页面就成功显示了
解决二:在render函数内return前线判断
例如:
render() { const {repName,repUrl} = this.state; if(!repName){ return <h2>LOADING...</h2> }else{ return <h2>Most star repo is <a href={repUrl}>{repName}</a></h2> } }
扩展:
扩展:在React组件中如何通过AJAX请求来加载数据呢?
首先,AJAX请求的源URL应该通过props传入;其次,最好在componentDidMount函数中加载数据。加载成功,将数据存储在state中后,通过调用setState来触发渲染更新界面。
一般将数据请求Ajax方法写在组件的hook函数componentDidMount 中,这样一旦页面加载完毕就开始执行Ajax函数。
从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
对于同步的状态改变,是可以放在componentWillMount,对于异步的,最好好放在componentDidMount。
参考代码:
import React from 'react' import {Form,Select,Button,Upload,Radio,DatePicker} from 'antd' //日期中文 import 'moment/locale/zh-cn'; import locale from 'antd/es/date-picker/locale/zh_CN'; import axios from 'axios'//引入axios const { RangePicker } = DatePicker; const layout = { labelCol: { span: 6 }, wrapperCol: { span: 12 }, }; const labelCol={ span: 3, offset: 12 } const validateMessages = { required: '${label} 不能为空!',//必选规则 types: { email: '${label} is not validate email!', number: '${label} is not a validate number!', }, number: { range: '${label} 必须在 ${min} 和 ${max}之间', }, }; //绑定上传的date const normFile = e => {//这个很重要,如果没有将上传失败并报错 console.log('Upload event:', e); if (Array.isArray(e)) { return e; } return e && e.fileList; }; // ------------------------------------------------------------------------------------------------------------- class FormMonth extends React.Component{ constructor(props){ super(props) this.state={ test:null, test2:[1,2,3] } } formRef = React.createRef(); onFill = () => {//给选择框等设置默认值 this.formRef.current.setFieldsValue({ jiemu:'节目一', reapeat:'每天', onJiemu:'是' }) console.log(this.formRef.current.getFieldValue())//这里能够获取到初始化挂载的值 }; //ajax--------------------------------------------- ajaxhostServe=()=>{//服务器请求 // 涉及到跨域问题,要在开发环境中,想要正常访问到8000端口的服务,我们需要代理。 // 代理的做法是:在项目的package.json文件添加“proxy”属性,并重新运行npm start //"browserslist": ...同级下 // "proxy": "http://localhost:8000" //既可访问本地 也可访问新开启的服务器所访问的文件 // axios.get('/api/users') // .then( (response)=> { // // handle success // console.log(response); // }) // .catch( (error)=> { // // handle error // console.log(error); // }) fetch('/api/users').then(res => { console.log(res) return res.json() }).then(data => { console.log(data) this.setState({test: data}) }) } ajaxFetch=()=>{//发送的网络请求 fetch('/static/ajax.json').then(res => { console.log(res) return res.json() }).then(data => { console.log(data) this.setState({test: data}) }) } ajaxAxios=()=>{ axios.get('/static/ajax.json') .then( (response)=> { // handle success console.log(response); if(response){ this.setState({ test:response.data }) } }) .catch( (error)=> { // handle error console.log(error); }) } // 周期函数-------------------------------------- // componentWillMount(){//将要挂载时 请求接口在这里通常 // this.ajaxAxios() // } // componentWillUnmount(){//销毁前 -切换到其它页面组件时会调用 // console.log('unmounted') // // console.log(this.state.test)//能够请求到 // } componentDidMount(){//挂载时 获取ref要在这里就可以设置默认值 // this.ajaxFetch() this.onFill() this.ajaxAxios() // this.ajaxhostServe()//从服务器上面获取的数据 // console.log(this.state.test)//null 请求不到数据为空 } render(){ console.log(this.state.test)//能够请求到数据 // this.onFill()//这时候获取formRef 会报错 const OptArr=['节目一','节目二','节目三','节目四','节目五','节目六'] const {Option} = Select const onFinish = (v)=>{ // console.log(v) const timer=v['choseTimer'] const value={ ...v, 'choseTimer':[timer[0].format('YYYY-MM-DD h:mm:ss'),timer[1].format('YYYY-MM-DD h:mm:ss')] } console.log(value) } const test = this.state.test return( <div> {/* { test.map((v,i)=>{ return( <div key={i}>{v.name}</div> ) }) } 不带判断报错信息: Cannot read property 'map' of null */} {/* {test instanceof Array?'数组':"非数组"} */} { test instanceof Array ? ( <div> { test.map((v,i)=>{ return( <div key={i}>{v.name}</div> ) }) } </div>) : ( <div> </div> ) } <Form ref={this.formRef} {...labelCol} {...layout} onFinish={onFinish}> {/* 选择节目 */} <Form.Item name="jiemu" label="节目"> <Select> { OptArr.map((v)=>{ return( <Option key={v} value={v}>{v}</Option> ) }) } </Select> </Form.Item> {/* 上传 */} {/* valuePropName="fileList" getValueFromEvent={normFile} 这两个需同时*/} <Form.Item name="upload" valuePropName="fileList" getValueFromEvent={normFile} label="上传"> <Upload name="logo" action="/upload.do" listType="picture"> <Button>添加素材</Button> </Upload> </Form.Item> {/* 重复 */} <Form.Item label="重复" name="reapeat"> <Radio.Group> <Radio value="每天">每天</Radio> <Radio value="每周">每周</Radio> <Radio value="每月">每月</Radio> <Radio value="特别日">特别日</Radio> <Radio value="自定义">自定义</Radio> </Radio.Group> </Form.Item> {/*开机节目*/} <Form.Item label="开机节目" name="onJiemu"> <Radio.Group> <Radio value="是">是</Radio> <Radio value="否">否</Radio> </Radio.Group> </Form.Item> {/*日期选择*/} <Form.Item label='日期选择' name='choseTimer'> <RangePicker locale={locale} showTime></RangePicker> </Form.Item> {/*提交*/} <Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 6 }}> <Button type='primary' htmlType="submit">提交</Button> </Form.Item> </Form> </div> ) } } export default FormMonth
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!