使用REACT.JS从JSON文件中的提取请求中获取未定义的值

时间:2019-02-26 10:28:40

标签: reactjs

我来自Vue环境,对此我有些困惑, 我读了其他类似的问题,但我无法解决问题,

为什么我不能回显从获取请求中获取的嵌套对象的值?

我在console.log之后setState,得到了值,但在渲染器中未定义,

import React, { Component } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends Component {
  constructor() {
    super();
    this.state = {
      isLoading: true,
      articles: {}
    };
  }

  componentDidMount() {
    this.setState({ loading: true });
    fetch("./articles.json")
      .then(response => response.json())
      .then(result => {
        this.setState({
          isLoading: false,
          article: result.blog.article
        });
        console.log(
          "componentDidMount__this.state.article=",
          this.state.article.link.title
        ); //this gets the value
      })
      .catch(error => {
        console.error(error);
      });
  }

  render() {
    //let articleTitle;
    // this gets error ----> console.log(this.state.article.link.title);
    // because .link is undefined

    // console.log(this.state.article);
    // if (this.state.article !== "undefined") {
    //   console.log("wait what?..");
    // if I changed the state in fetch why this stil
    //   articleTitle = this.state.article.link.title;
    // } else {
    //   articleTitle = "";
    // }

    // I assign "this.state.article.link.title" to a variable so I can avoid the error,
    //
    return (
      <div className="App">
        {/*<h1>{articleTitle}</h1> */}
        <h1>{this.state.article.link.title}</h1>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

articles.json

{
  "blog": {
    "article": {
      "id": 1,
      "title": " 1 lorem ipsum",
      "description": "lorem ipsum",
      "image": {
        "desktop": "https://via.placeholder.com/900x500?text=desktop",
        "tablet": "https://via.placeholder.com/600x400?text=tablet",
        "mobile": "https://via.placeholder.com/320x320?text=mobile"
      },
      "link": {
        "title": "lorem link",
        "url": "#"
      },
      "author": {
        "avatar": "https://via.placeholder.com/125x125?text=125x125",
        "name": "lorem ipsum"
      }
    }
  }
}

https://codesandbox.io/s/wo65w21kl5

4 个答案:

答案 0 :(得分:0)

在渲染器中使用动态状态之前,您必须进行检查,因为在组件安装和更新时都会调用动态状态。

这应该可以正常工作:

{this.state.isLoading ? '' : this.state.article.link.title}

答案 1 :(得分:0)

似乎this.state.article.link.title被引用时this.state.article === undefined

解决方案是更安全地检索this.state.article.link.title

通常通过利用short-circuit evaluation来实现。在下面的示例中,我还使用了destructuring assignmentdefault parameters

还建议将默认值分配给this.state,尤其是在处理不确定数据时。

// Default `this.state`.
this.state = {
  article: {link: {title: ''}},
  articles: {},
  isLoading: true,
}

// Safe retrieval of `title`.
const {article = {}} = this.state
const {link = {}} = article.link
const title = link.title || ''

答案 2 :(得分:0)

尝试

   import React, { Component } from "react";
    import ReactDOM from "react-dom";

    import "./styles.css";

    class App extends Component {
      constructor() {
        super();
      }
      state = {
        isLoading: true,
        articles: {}
      };
      componentDidMount() {
        this.setState({ loading: true });
        fetch("./articles.json")
          .then(response => response.json())
          .then(result => {
            this.setState({
              isLoading: false,
              articles: result.blog.article
            });
          })
          .catch(error => {
            console.error(error);
          });
      }

      render() {
        let Test = this.state.articles ? (
          <div className="App">
            <h1>{this.state.articles.title}</h1>
          </div>
        ) : null;

        console.log(this.state.articles.title);
        return <div>{Test}</div>;
      }
    }

    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);

答案 3 :(得分:0)

似乎render方法在fetch方法完成之前被调用了3次,因此在render方法this.state.character.name中是空对象。您还想知道为什么教程中的家伙在tutorial you mentioned对象中使用了这个问题:this.state.articles.link.title和您的代码this.state.character.name。这是不同的,因为可以使用this.state.article.link.title(它引用空对象的属性,因此它将返回未定义的值,而您的const obj = {}; console.log(obj.property); //undefined console.log(obj.link.title); // Uncaught TypeError: Cannot read property 'title' of undefined (它尝试访问不存在的对象的属性) )。您可以在控制台中对其进行检查:

Microsoft.Typescript.MSBuild