使用反应chartjs时,应用api / json错误

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

谢谢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,{Component};从'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. 的package.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
2个回答
0
投票

不要直接修改状态。始终使用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永远不会使用更新的数据重新渲染。


0
投票

第一:如果你想修改组件的状态,你必须使用this.setState({...}) React函数来执行它,如果不这样做,则反应不会再次触发渲染功能。所以你需要改变加载数据的方式:

    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原型是readonly所以你应该创建一个新的函数来格式化它在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);
    })
  }
© www.soinside.com 2019 - 2024. All rights reserved.