【问题标题】:React DOM gets rendered before the ajax requestReact DOM 在 ajax 请求之前被渲染
【发布时间】:2017-08-16 20:41:25
【问题描述】:

您好,我是 react 新手,我正在尝试构建一个应该显示图表的 react 组件,我正在使用融合图表来执行此操作。我需要通过 API 动态获取数据以将其提供给图表。但是图表在没有数据的情况下呈现,并且仅在加载图表后才启动 ajax 请求。我还想知道一旦数据可用,如何重新渲染 ReactDOM

我的代码sn-p:

import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery'
import FusionCharts from 'fusioncharts';
import ReactFC from 'react-fusioncharts';
import chart from 'fusioncharts/fusioncharts.charts';
class MyApp extends React.Component {
      render() {
          var chartData;
                $.ajax({
                type: "GET",
                url: 'someurl',
                dataType: "json",
                success: function (data) {    
                chartData =data;
                alert(chartData);
 }
            });

          var chartConfigs = {
    type: "Column2D",
    className: "fc-column2d", // ReactJS attribute-name for DOM classes
    dataFormat: "JSON",
    dataSource: {
        chart:{},
        data: chartData
    }
};  
        return (
            <div>< ReactFC {...chartConfigs }/></div>  

        );
    }
}

ReactDOM.render(
    <MyApp />,
    document.getElementById('chart-container')
);

【问题讨论】:

  • 不要在渲染中添加 ajax 代码...使用生命周期方法 - facebook.github.io/react/docs/react-component.html 这属于 componentWillMount(){},您应该渲染一些占位符,例如“正在加载” - 然后在数据到达时更改状态.
  • @DimitarChristoff Depends-didMount 是官方推荐的,除非您使用服务器端渲染的解决方法。
  • 可能是真的,但它允许您在渲染之前进行其他组合,例如设置状态,所以我更喜欢willMount / willUnmount。我的标准是:如果该操作不需要触摸/使用 DOM,请在渲染之前急切/尽早执行,否则,等待挂载。不过,说实话,我已经有一段时间没有编写具有后端领域知识的 UI 组件了,它不仅仅将其数据作为道具获取。这只是在考虑 redux 或 mobx 等模型之前让事情正常工作的快速技巧。

标签: jquery ajax reactjs fusioncharts


【解决方案1】:

编辑

由于指针this 这里很棘手。所以在ajax 调用之前,您需要通过分配that = this 来指向“当前”对象。

另一种方法是绑定ajax 函数。

$.ajax({...}).bind(this)


我会将您的chartData 存储在state 中。然后按照@Dimitar Christoff 所述,在componentWillMount 中执行ajax。 ajax调用完成后,使用setState触发render

import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery'
import FusionCharts from 'fusioncharts';
import ReactFC from 'react-fusioncharts';
import chart from 'fusioncharts/fusioncharts.charts';
class MyApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chartData: null; // OR whatever type to fit your data
    }
  }
  
  componentWillMount() {
    let that = this
    $.ajax({
      type: "GET",
      url: 'someurl',
      dataType: "json",
      success: function (data) {
        console.log(data);
        that.setState({chartData: data});
      }
    });
  }
  
  render() {
    let chartConfigs = {
      type: "Column2D",
      className: "fc-column2d", // ReactJS attribute-name for DOM classes
      dataFormat: "JSON",
      dataSource: {
          chart:{},
          data: chartData
      }
    };  
    
    return (
      <div><ReactFC {...chartConfigs }/></div>  
    );
  }
}

ReactDOM.render(
    <MyApp />,
    document.getElementById('chart-container')
);

【讨论】:

  • 我在之前的 componentDidMount() 中尝试过类似的方法,但这对我没有帮助。当我尝试执行代码时,我收到错误说明 this.setState 不是函数并且我的图表没有呈现。我错过了什么吗?这种反应对我来说是全新的,我只是想学习
  • @Firice Nguyen 这确实有助于摆脱 this.setState 错误。但我仍然面临一些问题。这里应该给出什么(数据:chartData)。是不是类似(数据:this.state.chartData)
  • @JDP:是的,你是对的。它应该是data: this.state.chartDatarender 内。你现在有什么问题?
  • 我遇到了一些不相关的问题 Uncaught TypeError: Cannot read property 'length' of undefined。我不明白这是在哪里发生的,为什么图表没有呈现
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-23
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 2016-10-10
  • 2021-01-04
相关资源
最近更新 更多