ReactJS处理空JSON数组问题:域名查询API返回空数组报错
解决API返回空数组时前端读取属性报错的问题
问题根源
你遇到的TypeError: Cannot read properties of undefined (reading 'domain'),核心原因是在判断数组是否为空之前,就直接尝试读取空数组的第一个元素属性。当后端返回空数组[]时,datar.data[0]是undefined,再去访问.domain自然会报错。
另外你代码里的JSON.parse(JSON.stringify(resp))完全多余——axios已经自动把后端返回的JSON响应解析成了JavaScript对象/数组,直接用resp.data就行,没必要多做一次序列化再解析。
解决方案
1. 前端逻辑修复(核心)
调整代码顺序,先判断返回的数组是否为空,再处理数据。修改后的前端代码如下:
const whoisForm = async (e) => { e.preventDefault(); try { const resp = await axios.post("http://localhost:3001/whois", { domain: domain, }); // 直接用axios解析好的resp.data,去掉多余的JSON转换 const domainData = resp.data; Moment.locale("en"); let successDomain = `${domain} is available for purchase, you can register it now!`; // 先判断数组是否为空,为空则直接设置成功提示并返回 if (domainData.length === 0) { setSuccessMesaj(successDomain); return; } // 数组有数据时再处理已注册的情况 let DomainWhois = domainData[0].domain; let DomainCreatedAt = Moment(domainData[0].createdAt).format("DD MMM YYYY"); setDomainWhois(DomainWhois); setDomainCreatedAt(DomainCreatedAt); let eroareDomain = `${DomainWhois} is already taken and was registered on: ${DomainCreatedAt}`; setEroareMesaj(eroareDomain); } catch (error) { console.log("error:", error); } };
关键修改点:
- 移除多余的
JSON.parse(JSON.stringify(resp)),直接使用resp.data - 把数组为空的判断逻辑前置,避免后续访问
undefined的属性 - 用模板字符串简化字符串拼接,提升代码可读性
2. 后端代码优化(可选但推荐)
当前后端代码中,findAll返回空数组时,if(result)会被判定为true(空数组在JavaScript中属于真值),所以会正常返回空数组。不过可以优化代码,确保无论查询结果如何都能返回响应,避免出现无响应的情况:
import Domains from "../models/DomainsModel.js"; export const Whois = async (req, res) => { try { const { domain } = req.body; // 直接await获取结果,移除嵌套的then,简化代码 const domainz = await Domains.findAll({ where: { domain }, attributes: { exclude: ["id", "userEmail", "arecord", "updatedAt"] }, raw: true, }); console.log(domainz); // 无论结果是空数组还是有数据,都返回响应 res.json(domainz); } catch (error) { console.log(error); // 出错时返回明确的错误响应,方便前端调试 res.status(500).json({ error: error.message }); } };
优化点:
- 用
await替代嵌套then,代码结构更清晰 - 确保任何情况都返回响应,避免前端请求超时
- 增加错误状态码和错误信息,便于定位问题
为什么之前的判断方式没用?
你之前尝试的datar.data.length === 0或!Array.isArray(datar.data) || !datar.data.length本身是有效的,但问题是你把这些判断放在了访问datar.data[0].domain之后——报错已经触发,后面的判断根本没机会执行。只要把判断逻辑提前,就能解决问题。
内容的提问来源于stack exchange,提问作者FBK
相关产品推荐
相关产品推荐

