如何在 React 中正确地 fetch() JSON

Posted

技术标签:

【中文标题】如何在 React 中正确地 fetch() JSON【英文标题】:How to properly fetch() JSON in React 【发布时间】:2019-07-17 07:22:53 【问题描述】:

我正在尝试从 url 获取一些 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>
      
    )
  

【问题讨论】:

【参考方案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>
      
    )
  

【讨论】:

谢谢!就是这样。我应该知道在渲染方法中调用 setState ......哎呀!我还必须在我的 renderData 函数中过滤我的数组:) 很高兴帮助了 Eli :-)【参考方案2】:

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

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>
))

【讨论】:

以上是关于如何在 React 中正确地 fetch() JSON的主要内容,如果未能解决你的问题,请参考以下文章

在序列中调用 React js Fetch 调用

react 之 fetch 登录请求formData提交参数

React.js:使用 Fetch API 和对象数组中的道具加载 JSON 数据

React JS - 如何通过 fetch 语句验证凭据

如何使用 React.js 中的 Fetch API 将数据发布到数据库

如何在 expo 中禁用 https-only fetch 请求 react native/node js