使用d3.csv加载数据后无法更新React中的状态

时间:2019-07-13 16:31:11

标签: reactjs csv d3.js

我正在使用React使用D3v4构建力仿真。但是,只有在对象阵列已经处于我的状态(在本例中为节点)的情况下,并且如果尝试从csv文件读取它并使用setState时,它才能工作。同样在我的Force.js文件中,当我尝试为ForceX设置this.props.width / 2,为ForceY设置this.props.height / 2时,它不起作用,我不得不直接为ForceX输入400 250来让ForceY发挥作用。

如果有人可以向我指出正确的方向,那就太好了!

不使用d3.csv的有效版本:

App.js

import React, { Component } from "react";
import * as d3 from "d3";
import Force from "./Force";


class App extends Component {


      state = {
        width: 800,
        height: 500,
        nodes: [
        {
          "ID": 1,
          "name": "Chlamydoselachus africana",
          "url": "https://en.wikipedia.org/wiki/Chlamydoselachus_africana",
          "common_name": "African frilled shark",
          "size": 117,
          "family": "Chlamydoselachidae",
          "family_common": "Frilled Sharks",
          "min_depth": 300,
          "max_depth": 1400,
          "IUCN": "NA",
          "CITES": 0,
          "baum": "",
          "family_grouped": "Frilled Sharks"
        },
        {
          "ID": 2,
          "name": "Chlamydoselachus anguineus",
          "url": "https://en.wikipedia.org/wiki/Chlamydoselachus_anguineus",
          "common_name": "Frilled shark",
          "size": 150,
          "family": "Chlamydoselachidae",
          "family_common": "Frilled Sharks",
          "min_depth": 0,
          "max_depth": 1570,
          "IUCN": "LC",
          "CITES": 0,
          "baum": "",
          "family_grouped": "Frilled Sharks"
        },
        {
          "ID": 3,
          "name": "Heptranchias perlo",
          "url": "https://en.wikipedia.org/wiki/Heptranchias_perlo",
          "common_name": "Sharp-nose sevengill shark",
          "size": 140,
          "family": "Hexanchidae",
          "family_common": "Cow Sharks",
          "min_depth": 0,
          "max_depth": 1000,
          "IUCN": "NT",
          "CITES": 0,
          "baum": "",
          "family_grouped": "Cow Sharks"
        },
        {
          "ID": 4,
          "name": "Hexanchus griseus",
          "url": "https://en.wikipedia.org/wiki/Hexanchus_griseus",
          "common_name": "Blunt-nose sixgill shark",
          "size": 790,
          "family": "Hexanchidae",
          "family_common": "Cow Sharks"
        },
        {
          "ID": 5,
          "name": "Hexanchus nakamurai",
          "url": "https://en.wikipedia.org/wiki/Hexanchus_nakamurai",
          "common_name": "Bigeyed sixgill shark",
          "size": 180,
          "family": "Hexanchidae",
          "family_common": "Cow Sharks"
        },
        {
          "ID": 6,
          "name": "Hexanchus vitulus",
          "url": "https://en.wikipedia.org/wiki/Hexanchus_vitulus",
          "common_name": "Atlantic sixgill shark",
          "size": 220,
          "family": "Hexanchidae",
          "family_common": "Cow Sharks"
        },
        {
          "ID": 7,
          "name": "Notorynchus cepedianus",
          "url": "https://en.wikipedia.org/wiki/Notorynchus_cepedianus",
          "common_name": "Broad-nose sevengill shark",
          "size": 300,
          "family": "Hexanchidae",
          "family_common": "Cow Sharks"
        },
        {
          "ID": 8,
          "name": "Centrophorus atromarginatus",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_atromarginatus",
          "common_name": "Dwarf gulper shark",
          "size": 87,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 9,
          "name": "Centrophorus granulosus",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_granulosus",
          "common_name": "Gulper shark",
          "size": 100,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 10,
          "name": "Centrophorus harrissoni",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_harrissoni",
          "common_name": "Dumb gulper shark",
          "size": 110,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 11,
          "name": "Centrophorus moluccensis",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_moluccensis",
          "common_name": "Small-fin gulper shark",
          "size": 98,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 12,
          "name": "Centrophorus seychellorum",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_seychellorum",
          "common_name": "Seychelles gulper shark",
          "size": 80,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 13,
          "name": "Centrophorus squamosus",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_squamosus",
          "common_name": "Leaf-scale gulper shark",
          "size": 158,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 14,
          "name": "Centrophorus tessellatus",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_tessellatus",
          "common_name": "Mosaic gulper shark",
          "size": 89,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        },
        {
          "ID": 15,
          "name": "Centrophorus uyato",
          "url": "https://en.wikipedia.org/wiki/Centrophorus_uyato",
          "common_name": "Little gulper shark",
          "size": 110,
          "family": "Centrophoridae",
          "family_common": "Gulper Sharks"
        }],
        margin:{left:10,top:10,right:10,bottom:10}
      };


        render() {
          return (
            <Force width={this.state.width} height={this.state.height} data={this.state.nodes} />
          );
        }
      }


export default App;

Force.js

import React from "react";
import * as d3 from "d3";
import _ from "lodash";

class Force extends React.Component {


  constructor(props){
    super(props);

    var forceSim;

  }
      componentDidMount() {

       var radiusScale = d3.scaleSqrt()
           .range([0,0.7]);

        this.forceSim = d3.forceSimulation(this.props.data)
      .force('x', d3.forceX(function(d) {
               return 400
           }).strength(0.03))
           .force('y', d3.forceY(function(d) {
               return 250
           }).strength((0.03)))
           .force('collide', d3.forceCollide(function(d) {
               return radiusScale(+d.size)
           })).velocityDecay(0.1).alphaDecay(0.01);

      this.forceSim.on('tick', () => this.setState({nodes: this.props.data}));

      }

      componentWillUnmount() {
          this.forceSim.stop();
        }

            render() {
            var colorScale = d3.scaleOrdinal()
                .range(['#450303', '#6e0505', '#951f1f'
                ]);
                var radiusScale = d3.scaleSqrt()
                    .range([0.5,0.9]);
            return (
                <svg width={this.props.width} height={this.props.height}>
                {this.props.data.map((node, index) =>(
                    <circle r={radiusScale(node.size)} cx={node.x} cy={node.y} fill={colorScale(node.family)} key={index}/>
                ))}
              </svg>
            );
          }
        }


export default Force;

使用d3.csv的版本无效,但我想使其正常工作:

App.js

import React, { Component } from "react";
import * as d3 from "d3";
import Force from "./Force";
import data from './data.csv';

class App extends Component {

      state = {
        width: 800,
        height: 500,
        nodes: [],
        margin:{left:10,top:10,right:10,bottom:10}
      };

      componentDidMount() {

       d3.csv(data).then(function(data) {
         console.log(data)
         this.setState(prevState =>({
          nodes: data
         }))
       }).catch(function(err) {
           throw err;
       })
    }


        render() {
          return (
            <Force width={this.state.width} height={this.state.height} data={this.state.nodes} />
          );
        }
      }


export default App;

Force.js

this.forceSim = d3.forceSimulation(this.props.data)
          .force('x', d3.forceX(function(d) {
                   return (this.props.width)/2  ////HERE
               }).strength(0.03))
               .force('y', d3.forceY(function(d) {
                   return (this.props.height)/2  ////HERE
               }).strength((0.03)))
               .force('collide', d3.forceCollide(function(d) {
                   return radiusScale(+d.size)
               })).velocityDecay(0.1).alphaDecay(0.01);

这是csv文件数据:

ID,名称,URL,通用名称,大小,家庭,家庭通用 1,Chlamydoselachus africana,https://en.wikipedia.org/wiki/Chlamydoselachus_africana,African褶边鲨,117,Chlamydoselachidae,褶边鲨 2,Chlamydoselachus anguineus,https://en.wikipedia.org/wiki/Chlamydoselachus_anguineus,Frilled鲨鱼,150,Chlamydoselachachae,褶边鲨鱼 3,Heptranchias perlo,https://en.wikipedia.org/wiki/Heptranchias_perlo,Sharp-nose sevengill shark,140,Hexanchidae,Cow Sharks 4,Hexanchus griseus,https://en.wikipedia.org/wiki/Hexanchus_griseus,Blunt-nose sixgill shark,790,Hexanchidae,Cow Sharks 5,Hexanchus nakamurai,https://en.wikipedia.org/wiki/Hexanchus_nakamurai,Bigeyed Sixgill shark,180,Hexanchidae,Cow Sharks 6,Hexanchus vitulus,https://en.wikipedia.org/wiki/Hexanchus_vitulus,Atlantic Sixgill鲨鱼,220,Hexanchidae,Cow Sharks 7,Notorynchus cepedianus,https://en.wikipedia.org/wiki/Notorynchus_cepedianus,Broad-nose,七g鲨,300,六ch科,牛鲨 8,Centrophorus atromarginatus,https://en.wikipedia.org/wiki/Centrophorus_atromarginatus,Dwarf食尸鲨,87,Centrophoridae,Gulper Sharks 9,Centrophorus granulosus,https://en.wikipedia.org/wiki/Centrophorus_granulosus,Gulper鲨鱼,100,Centrophoridae,Gulper鲨鱼 10,Centrophorus harrissoni,https://en.wikipedia.org/wiki/Centrophorus_harrissoni,Dumb食尸鲨,110,Centrophoridae,Gulper Sharks 11,Centrophorus moluccensis,https://en.wikipedia.org/wiki/Centrophorus_moluccensis,Small-fin食尸鲨,98,Centrophoridae,Gulper Sharks 12,雪松草,https://en.wikipedia.org/wiki/Centrophorus_seychellorum,Seychelles ul鲨,80,C科,G鲨 13,Centrophorus squamosus,https://en.wikipedia.org/wiki/Centrophorus_squamosus,Leaf-scale食尸鲨,158,Centrophoridae,Gulper Sharks 14,中华en(Centrophorus tessellatus),https://en.wikipedia.org/wiki/Centrophorus_tessellatus,Mosaic食尸鲨,89,食蟹科,食尸鲨

1 个答案:

答案 0 :(得分:1)

错误在于匿名函数和class。 这对this的工作方式有很好的解释:https://stackoverflow.com/a/3127440/5122581


在您的代码中:

this

您使用匿名函数将promise传递给了then回调。该函数没有您期望的d3.csv(data).then(function(data) { console.log(data) this.setState(prevState =>({ nodes: data })) }).catch(function(err) { throw err; }) 绑定。有三种解决方案:

箭头功能:

this

为外部范围内的d3.cvs(data).then((data) => { this.setState({ nodes: data }); }); 创建变量:

this

绑定功能:

const self = this;

d3.cvs(data).then(function(data) {
  self.setState({ nodes: data });
});

由于您已经在使用箭头功能,所以我认为它们是最简洁,优雅的解决方案