javascript - 获取后访问状态以显示它

标签 javascript reactjs fetch this state

我想显示一些获取的信息,这些信息存储在带有反应的状态中。

  constructor(props) {
    super(props);
    this.state = { price: [] };
  }

  fetchResult = () => {
    fetch('https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD,EUR', {
    })
      .then(response => {
        return response.json();
      })
      .then(price => {
        this.setState({ price: price })
        console.log("TCL: price", price);
        console.log("TCL: this.state.price.BTC.USD", this.state.price.BTC.USD)
      })
      .catch(error => {
        console.error(error);       
      });
  }

  componentDidMount = () => {
    this.fetchResult()
    setInterval(this.fetchResult, 30000000)
  }  

render() {

    return (

         <div className="overviewcard">

            <p>{this.state.price}</p>
            <p>{this.state.price.BTC.USD}</p>

         </div>

    );
  }

// Console.log(price) = {"BTC":{"USD":10208.24,"EUR":9228.96},"ETH":{"USD":213.4,"EUR":192.97}}  
// Console.log(this.state.price.BTC.USD) = 10208.24

所以当我尝试用以下方式显示它时:

{this.state.price.BTC.USD}

我收到此错误:

"TypeError: Cannot read property 'USD' of undefined"

{this.state.price}

我收到此错误:

"Objects are not valid as a React child"

我阅读了其他主题,但没有找到任何解决方案,我尝试绑定(bind)“this”并放置函数箭头。我不知道该怎么办。

感谢您的帮助

最佳答案

您的代码存在一些问题:

  1. 您在初始状态下将 price 设置为空数组,但随后尝试将其作为对象访问。将初始状态更改为 this.state = {price: {} };

  2. setState 是异步的,因此设置后直接将其记录到控制台将显示旧值,您需要使用 setState 的回调:

this.setState({ price: price } , () => {
  console.log("state:", this.state);
})

  • 您正在尝试渲染 this.state.price,但它应该是一个对象,因此这就是您收到错误的原因。

  • 请勿在 componentDidMount 中使用 setInterval,因为它会使用相同的 url 重复调用您的 api 获取方法。

  • 您正在尝试渲染 this.state.price.BTC.USD,但是在获取数据并将其设置为状态之前,状态上的价格值不会拥有任何 props,您将收到 cannot access property 'BTC' of undefined 错误。在这种情况下,更好的想法是延迟渲染,直到获取数据。您可以通过同时显示加载程序来做到这一点。此外,最好进行一些错误处理,如果数据获取不成功,您将显示一条错误消息:

  •   constructor(props) {
        super(props);
        this.state = {
          price: {},
          error: false, // Track error state
          loading: true // set loading to true in the beginning
        };
      }
    
      fetchResult = () => {
        this.setState({ error: false });
        fetch(
          "https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD,EUR",
          {}
        )
          .then(response => {
            return response.json();
          })
          .then(price => {
            this.setState(
              {
                price: price,
                loading: false // Disable loading after data is fetched
              },
              () => {
                console.log("state:", this.state);
              }
            );
          })
          .catch(error => {
            console.error(error);
            this.setState({ error: true, loading: false });  // Also disable loading in case of error
          });
      };
    
      componentDidMount = () => {
        this.fetchResult();
      };
    
      render() {
        if (this.state.error) {
          return <p>Error message here</p>;
        }
        return this.state.loading ? (
          <p>Loading...</p> // Show loader before the data is ready
        ) : (
          <div className="overviewcard">
            <p>{this.state.price.BTC.USD}</p>
          </div>
        );
      }
    

    我最近写了一篇post关于 React 最常见的错误,您可能会发现它很有用。

    这里还有一个working sandbox .

    关于javascript - 获取后访问状态以显示它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57997339/

    相关文章:

    reactjs - React hooks - useEffect 方法不断获取

    javascript - React Router 和历史

    git - 如何获取 github repo readme 内容

    javascript - 删除存储有 'react-cookie' 的 cookie,无论域如何

    javascript - Context.Consumer 源值映射不渲染任何元素

    javascript - Here JavaScript API 3.0 - 如何实现可拖动标记

    javascript - Firebase PWA 不会在移动浏览器中对离线用户进行身份验证(在桌面上运行良好)

    javascript - 未找到成员(member)错误

    hibernate - 如何确定 OpenJPA 中 FetchBatchSize 的数量?

    javascript - Angularjs - 从 ng-option 返回数据