【问题标题】:ReactJS: Error while extracting data from JSON fileReactJS:从 JSON 文件中提取数据时出错
【发布时间】:2019-10-02 10:54:50
【问题描述】:

我正在尝试将数据从我的 JSON 文件传递​​到我的 ReactJS 应用程序,但收到以下错误:

TypeError: 无法读取未定义的属性'mainPage'

如果我只尝试 console.log siteData,它将运行良好。我猜这个问题可能与访问对象参数有关

你能告诉我我做错了什么吗?

这是我的 JSON 对象:

{
    "data": {
        "mainPage": {
            "navBar": ["HR", "HR1", "HR2"],
            "name": "Name one",
            "agency": "agency one"
        },

        "secondPage": {
            "rank": 2,
            "name": "Name Two",
            "agency": "agency two"
        },

        "thirdPage": {
            "rank": 3,
            "name": "Name Three",
            "agency": "agency three"
        }
    }
}

我的 .jsx 文件:

import React from 'react';
import axios from 'axios';
import logo from '../img/company_logo.png';
import '../css/header.scss';

export default class Header extends React.Component {
  constructor() {
    super();
    this.state = {
      siteData: {},
    };
  }

  componentDidMount() {
    axios.get('./data.json')
      .then((res) => {
        this.setState({
          siteData: res.data,
        });
      })
      .catch((err) => {
        console.log(err);
      });
  }

  render() {
    // console.log(this.state);
    const { siteData } = this.state;
    console.log(siteData.data.mainPage);

    return (
      <div className="headerWrapper">
        <a href=".../public/index.html">
        <img src={logo} alt="company_logo" id="companyLogo" />
        </a>
        <ul>
          <li>Navbar_1</li>
          <li>Navbar_2</li>
          <li>Navbar_3</li>
        </ul>
      </div>
    );
  }
}

【问题讨论】:

  • siteData.data 未定义。您可能缺少嵌套级别。试试siteData.mainPage?
  • 看起来 siteData.data 未定义,请检查您是否使用控制台或警报获取数据
  • 如果我 console.log siteData.data 它会显示我的对象
  • 必须是siteData.mainPage

标签: javascript json reactjs


【解决方案1】:

这是因为componentDidMount 在组件的初始渲染之后运行。您可以检查组件here 的生命周期,其中声明:

componentDidMount() 方法在组件输出后运行 被渲染到 DOM。

在 render 方法中,您应该检查这是否为 null,与异步 (AJAX) Web 调用一样,无法保证您可以在初始渲染发生之前检索数据,即使您在渲染之前调用 AJAX发生。

【讨论】:

    【解决方案2】:

    您的 Header 组件的 render() 方法正在尝试访问最初未定义的 datamainPage 字段。

    要记住的是,组件render() 方法将在axios.get() 请求完成之前被调用。这通常意味着您希望在 axio 请求正在进行时呈现“正在加载”消息,或一起跳过呈现(如下所示)。

    要应用这些想法,请考虑修改您的组件,如下所示:

    export default class Header extends React.Component {
      constructor() {
        super();
        this.state = {
          /* siteData: {}, Remove this */
        };
      }
    
      componentDidMount() {
        axios.get('./data.json')
          .then((res) => {
            this.setState({
              siteData: res.data,
            });
          })
          .catch((err) => {
            console.log(err);
          });
      }
    
      render() {
        // console.log(this.state);
        const { siteData } = this.state;
    
        /* If siteData not present, then data.json has not been loaded yet, so render nothing */
        if(!siteData) {
            return null;
        }
    
        /* The siteData is present in the component's state, so we can now access it, and render
        as per usual */
        console.log(siteData.data.mainPage);
    
        return (
          <div className="headerWrapper">
            <a href=".../public/index.html">
            <img src={logo} alt="company_logo" id="companyLogo" /></a>
            <ul>
              <li>Navbar_1</li>
              <li>Navbar_2</li>
              <li>Navbar_3</li>
            </ul>
          </div>
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      你可以试试这样吗? 我已经静态列出数据并通过 setState 而不是 api 调用以状态存储。 在 render 中,检查 siteData 中是否有数据,然后只映射数据,也可以通过 siteData 的长度检查。

      import React from 'react';
      import axios from 'axios';
      import logo from '../img/company_logo.png';
      import '../css/header.scss';
      
      export default class Roles extends React.Component {
      constructor() {
          super();
          this.state = {
              siteData: {},
          };
      }
      
      componentDidMount = () => {
          let allData = {
              "data": {
                  "mainPage": {
                      "navBar": ["HR", "HR1", "HR2"],
                      "name": "Name one",
                      "agency": "agency one"
                  },
      
                  "secondPage": {
                      "rank": 2,
                      "name": "Name Two",
                      "agency": "agency two"
                  },
      
                  "thirdPage": {
                      "rank": 3,
                      "name": "Name Three",
                      "agency": "agency three"
                  }
              }
          }
          this.setState({ siteData: allData.data })
      }
      
      render() {
          // console.log(this.state);
          const { siteData } = this.state;
          console.log(siteData && siteData.mainPage);
      
          return (
              <div className="headerWrapper">
                  <a href=".../public/index.html"><img src={logo} alt="company_logo" id="companyLogo" /></a>
                  <ul>
                      <li>Navbar_1</li>
                      <li>Navbar_2</li>
                      <li>Navbar_3</li>
                  </ul>
              </div>
          );
      }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多