You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React从Elasticsearch取数后刷新浏览器,报hits未定义错误如何解决?

解决React从Elasticsearch取数据时的"Cannot read properties of undefined (reading 'hits')"错误

问题根源

  1. 初始状态不匹配:你把data的初始值设为数组[],但Elasticsearch返回的是包含hits和_shards的对象,渲染时直接访问data.hits会因为数组没有hits属性而报错。
  2. 异步数据未就绪:组件首次渲染和刷新后,API请求还没完成就开始渲染表格,此时data还是初始值,访问深层属性必然抛出错误。

具体修复步骤

1. 初始化匹配返回结构的空状态

将data的初始值从数组改为符合Elasticsearch响应结构的空对象,确保渲染时不会因为属性不存在而崩溃:

const [data, setData] = useState({ 
  hits: { hits: [] }, 
  _shards: { failed: 0, skipped: 0, successful: 0, total: 0 } 
});

2. 使用可选链操作符避免深层属性报错

在渲染表格的每个数据项时,添加?.可选链操作符,确保即使某个层级未定义也不会抛出错误:
例如:

<td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._index, null, 2)}</pre></td>
<td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.ephemeral_id, null, 2)}</pre></td>

3. (可选)添加加载状态提升体验

增加一个loading状态,在API请求未完成时显示加载提示,避免用户看到空白或错误内容:

const [loading, setLoading] = useState(true);

// 在apiGet函数中修改:
fetch(ur1, requestOptions)
  .then(response => response.json())
  .then(result => {
    setData(result);
    setLoading(false); // 请求完成后关闭加载状态
  })
  .catch(error => {
    console.log('error', error);
    setLoading(false);
  });

// 渲染时判断:
if (loading) {
  return <div>加载中...</div>;
}

完整修改后的代码示例

import React, { useEffect, useState} from "react";
import './pages/table.css'

function JsonDataDisplay() {
    // 初始化匹配Elasticsearch响应结构的空状态
    const [data, setData] = useState({ 
        hits: { hits: [] }, 
        _shards: { failed: 0, skipped: 0, successful: 0, total: 0 } 
    });
    const [loading, setLoading] = useState(true);
  
    const apiGet = () => {
        var myHeaders = new Headers();
        myHeaders.append("Authorization", "Basic ZWxhc3RpYzpydHoxMDRpWGtjcV85RjZUTCtMMA==");

        var requestOptions = {
            method: 'GET',
            headers: myHeaders,
            redirect: 'follow'
        };

        const ur1 = 'https://192.168.1.3:9200/clientesafewindows-logstash/_search'

        fetch(ur1, requestOptions)
            .then(response => response.json())
            .then(result => {
                setData(result);
                setLoading(false);
                console.log(result);
            })
            .catch(error => {
                console.log('error', error);
                setLoading(false);
            });
    };

    useEffect(() => {
        apiGet();
    }, []);

    // 加载状态下显示提示
    if (loading) {
        return <div>加载数据中...</div>;
    }

    return (
        <div>
            <table className="table table-striped">
                <thead>
                    <tr>
                        <th>Index</th>
                        <th>Score</th>
                        {/* Agent */}
                        <th>Ephemeral_id</th>
                        <th>Id</th>
                        <th>Name</th>
                        <th>Type</th>
                        <th>Version</th>
                        {/* Event */}
                        <th>Original</th>
                        {/* Host */}
                        <th>Architecture</th>
                        <th>Hostname</th>
                        <th>Id</th>
                        <th>IP</th>
                        <th>MAC</th>
                        <th>Name</th>
                        {/* OS */}
                        <th>Build</th>
                        <th>Family</th>
                        <th>Kernel</th>
                        <th>Name</th>
                        <th>Platform</th>
                        <th>Type</th>
                        <th>Version</th>
                        {/* Input */}
                        <th>Type</th>
                        <th>Message</th>
                        {/* Shards */}
                        <th>Failed</th>
                        <th>Skipped</th>
                        <th>Success</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._index, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._score, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.ephemeral_id, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.id, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.name)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.type, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.agent?.version, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.event?.original)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.architecture, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.hostname, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.id)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.ip?.[7], null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.mac, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.name, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.build, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.family)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.kernel, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.name, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.platform, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.type)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.host?.os?.version, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.input?.type, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?.hits?.hits?.[1]?._source?.message, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?._shards?.failed, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?._shards?.skipped, null, 2)}</pre></td>
                        <td><pre>{JSON.stringify(data?._shards?.successful)}</pre></td>
                        <td><pre>{JSON.stringify(data?._shards?.total, null, 2)}</pre></td>
                    </tr> 
                </tbody>
            </table>
        </div>
    );
}

export default JsonDataDisplay;

内容的提问来源于stack exchange,提问作者khlinten demelash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:16:24