【问题标题】:Rest api / json error while using it with react chartjs与 react chartjs 一起使用时出现 Rest api / json 错误
【发布时间】:2019-02-20 20:56:43
【问题描述】:

感谢 Sergio 推荐的答案。我真的很喜欢您演示的答案,但问题是由于每个错误,我仍然无法看到图表。这里使用的api是使用AWS的lambda函数

  1. App.js

    import React, { Component } from "react";
    import axios from "axios";
    
    import Chart from "./chart";
    
    class App extends Component {
      constructor() {
        super();
    
        this.state = {
          labels: [],
          data: []
        };
      }
    
      componentDidMount() {
        this.getChartData();
      }
    
      getChartData() {
        Date.prototype.formatMMDDYYYY = () => {
          return (
            this.getDate() + 1 + "/" + this.getMonth() + "/" + this.getFullYear()
          );
        };
    
       axios.get('https://cors-anywhere.herokuapp.com/https://api.myjson.com/bins/zfpa2') 
         .then(results => {
          results.forEach(packet => {
            this.state.labels.push(new Date(packet.updated).formatMMDDYYYY());
            this.state.data.push(parseFloat(packet.users));
          });
           this.setState({ data, labels })
        })
         .catch(error => {
          console.log(error);
        })
      }
    
      render() {
        return (
          <div>
            <Chart labels={this.state.labels} data={this.state.data} />
          </div>
        );
      }
    }
    
     export default App;
    
  2. chart.js

    从'react'导入反应,{组件}; 从'react-chartjs-2'导入{Bar};

     class Chart extends Component {
     render() {
      const chartData = {
      labels: this.props.labels,
      datasets: [
                {
                  data: this.props.data,
                  backgroundColor: 'rgba(255, 99, 132, 0.6)',
                }
              ]
            }
      return (
         <div className="chart">
             <Bar 
                data={chartData}
                options={{
                    title: {
                        display: true,
                        text: 'Largest cities in Delhi',
                        fontSize: 25
                    },
                    legend: {
                        display: true,
                        position: 'right'
                    }
                }}
            />
        </div>
       );
      }
     }
    
     export default Chart;
    
  3. 包.json

       {
         "name": "apicharts",
         "version": "0.1.0",
         "private": true,
         "dependencies": {
           "axios": "^0.18.0",
           "chart.js": "^2.7.3",
           "jquery": "^3.3.1",
           "react": "^16.8.2",
           "react-chartjs-2": "^2.7.4",
           "react-dom": "^16.8.2",
           "react-scripts": "2.1.5",
           "react-vis": "^1.11.6"
         },
         "scripts": {
         "start": "react-scripts start",
         "build": "react-scripts build",
         "test": "react-scripts test",
         "eject": "react-scripts eject"
         },
        "eslintConfig": {
        "extends": "react-app"
         },
        "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
         ]
       }
    

请帮我解决这个问题

【问题讨论】:

    标签: javascript reactjs d3.js chart.js visualization


    【解决方案1】:

    直接修改状态。始终使用setState

    // BAD
    results.forEach(packet => {
      this.state.labels.push(new Date(packet.updated).formatMMDDYYYY());
      this.state.data.push(parseFloat(packet.users));
    });
    
    // GOOD
    const labels = [];
    const data = [];
    
    results.forEach(packet => {
      labels.push(new Date(packet.updated).formatMMDDYYYY());
      data.push(parseFloat(packet.users));
    });
    
    this.setState({ data, labels });
    

    当您直接修改状态时,组件永远不会重新渲染,这意味着 Chart 永远不会使用更新的数据重新渲染。

    【讨论】:

      【解决方案2】:

      第一:如果你想修改一个组件的状态,你必须使用this.setState({...})React 函数,如果你不这样做,react 不会再次触发render函数。所以你需要改变你加载数据的方式:

          const labels = [];
          const data = [];
          results.forEach(packet => {
            labels.push(new Date(packet.updated).formatMMDDYYYY());
            data.push(parseFloat(packet.users));
          });
          this.setState({
           labels,
           data
          })
      

      现在记住 constructor 只是在组件将要被挂载时被触发,所以如果你使用 props 中的值设置 chart.js 的状态,当父组件触发 setState 函数时,你的数据是不会更新。所以这里我们需要从constructor中删除以下内容:

      chartData: {
          labels: props.labels,
          datasets: [
                      {
                        data: props.data,
                        backgroundColor: 'rgba(255, 99, 132, 0.6)',
                       }
                    ]
       }
      

      并添加到render 函数中,例如:

      const chartData = {
              labels: props.labels,
              datasets: [
                          {
                            data: props.data,
                            backgroundColor: 'rgba(255, 99, 132, 0.6)',
                           }
                        ]
           }
      

      最后发送你最近创建的数据

      <Bar 
        data={chartData}
        options={{
            title: {
                display: true,
                text: 'Largest cities in Delhi',
                fontSize: 25
            },
            legend: {
                display: true,
                position: 'right'
            }
        }}
      />
      

      此外,由于您使用的是React,因此您不应该使用 jQuery。如果您只是使用它来加载数据,您可以使用其他替代方法,例如 axiosfetch 来获取数据:)

      编辑

      Date 原型是只读的,因此您应该创建一个新函数以将其格式化为App.js

      getFormatDate = (date) => {
          return (
            date.getDate() + 1 + "/" + date.getMonth() + "/" + date.getFullYear()
          );
        }
      

      使用以下代码修改您的getChartData 以解决问题:

      getChartData() {
         axios.get('https://cors-anywhere.herokuapp.com/https://api.myjson.com/bins/zfpa2') 
           .then(({ data }) => {
             const labels = [];
             const dataArray = [];
             data.forEach(packet => {
              labels.push(this.getFormatDate(new Date(packet.updated)));
              dataArray.push(parseFloat(packet.users));
            });
             this.setState({ data : dataArray, labels })
          })
           .catch(error => {
            console.log(error);
          })
        }
      

      【讨论】:

      • 嗨,塞尔吉奥,我真的很佩服你的帖子,但你能再次帮助我解决我面临的问题,即我无法显示图表。我已根据您的建议更新了问题。真的很期待您的回复。
      • 嗨@NikhilVaidyar,你能添加你项目的package.json吗?
      • 嗨@SergioEscudero,我在上面的问题上添加了package.json。您可以立即查看。
      猜你喜欢
      • 2019-06-04
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      相关资源
      最近更新 更多