如何在React中正确获取()JSON

问题描述 投票:0回答:2

我正在尝试从网址中获取一些json数据。然后我将我的状态设置为该数据的一部分。

在我的渲染方法中,我想使用map()显示数据

我面临的问题是,因为获取数据需要一些时间,所以在尝试渲染数据时,状态仍设置为null。

我遇到的另一个问题是我的getData()函数似乎每隔几秒重复一次。如果我在最后添加一个控制台日志,它会一遍又一遍地记录它。

如果他们能看到我做错了什么,有人能告诉我吗?

我的代码如下:

getData = () => {
    let _this = this
    fetch('https://my-data-link.com')
    .then(
      response => {
        if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' +
            response.status);
          return;
        }

        // Examine the text in the response
        response.json().then(
          data => {
            _this.setState({data: data.searchResults.filter(d => d.salesInfo.pricing.monthlyPayment <= _this.state.monthlyMax)})
          }
        );
      }
    )
    .catch(function(err) {
      console.log('Fetch Error :-S', err);
    });
    
    // Adding a console log here is when I noticed that the code keeps firing.
  }

  renderData = () => {
    let vehicles = "Loading..."
    let _this = this
    this.getData()
    setTimeout(function(){
      vehicles = _this.state.data.map(vehicle => (
        <h1>{vehicle.make}</h1>
      ))
      return vehicles
    }, 6000);

    return vehicles
  }
  
  render() {
    return (
      {this.state.formSubmitted > 0 &&
        <div>
          <h3 className="ch-mt--4">Recommended vehicles</h3>
          {this.renderData()}
        </div>
      }
    )
  }
reactjs api fetch state lifecycle
2个回答
1
投票

你有两个问题

第一:您在render方法中调用getData,在getData中调用setState实际上触发了一个循环。如果组件挂载只需触发一次,则在componentDidMount中触发它。

第二:不应该使用不可靠的setTimeout,而应该将状态数据初始化为构造函数中的空数组

constructor(props) {
    super(props);
    this.state = {
        data: [];
    }
}
componentDidMount() {
     this.getData();
}

getData = () => {
    let _this = this
    fetch('https://my-data-link.com')
    .then(
      response => {
        if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' +
            response.status);
          return;
        }

        // Examine the text in the response
        response.json().then(
          data => {
            _this.setState({data: data.searchResults.filter(d => d.salesInfo.pricing.monthlyPayment <= _this.state.monthlyMax)})
          }
        );
      }
    )
    .catch(function(err) {
      console.log('Fetch Error :-S', err);
    });


  }

  renderData = () => {
    let vehicles = "Loading..."
    if(this.state.data.length === 0) {
        return vehicles;
    }
    return this.state.data.map(vehicle => (
        <h1>{vehicle.make}</h1>
    ));
  }

  render() {
    return (
      {this.state.formSubmitted > 0 &&
        <div>
          <h3 className="ch-mt--4">Recommended vehicles</h3>
          {this.renderData()}
        </div>
      }
    )
  }

1
投票

您应该在getData中调用componentDidMount,如下所示:

componentDidMount() {
  this.getData()
}

此外,你不能在渲染方法中调用setState它将是无限循环,因为在调用设置状态render方法之后,因为renderData正在设置在render方法中调用的状态

您应该在渲染方法中执行以下操作,而不是setTimeOut

// in return of render method. It will display data from state after api call
{this.state.data && this.state.data.map(vehicle => (
    <h1>{vehicle.make}</h1>
))}
© www.soinside.com 2019 - 2024. All rights reserved.