如何使React.js从api获取数据作为状态并将此状态数据从其父级传递到子级组件

时间:2018-12-16 17:38:37

标签: reactjs d3.js fetch

我正在研究React.js + D3.js项目。我希望App.js从json文件中获取数据,并将该数据保存到状态中,并将该父状态数据通过属性传递到我的子组件状态。我发现如果我在App.js中使用静态数据,效果很好,但是一旦从json文件中获取数据,它就会失败,因为无法将任何数据存储到属性中。我的App.js像这样:

WorkTime

我的父亲是这样的:

import React, { Component } from 'react';
import SandkeyGraph from './particle/SandkeyGraph';

class App extends Component {
  state = {
    data : null
  }

  // works fine in this way!
  // state = {
  //   data: {
  //     "nodes":[
  //     {"node":0,"name":"node0"},
  //     {"node":1,"name":"node1"},
  //     {"node":2,"name":"node2"},
  //     {"node":3,"name":"node3"},
  //     {"node":4,"name":"node4"}
  //     ],
  //     "links":[
  //     {"source":0,"target":2,"value":2},
  //     {"source":1,"target":2,"value":2},
  //     {"source":1,"target":3,"value":2},
  //     {"source":0,"target":4,"value":2},
  //     {"source":2,"target":3,"value":2},
  //     {"source":2,"target":4,"value":2},
  //     {"source":3,"target":4,"value":4}
  //     ]}
  // }

  componentWillMount() {
    this.getData('./data/sankey.json');
  }

  getData = (uri) => {
    fetch(uri)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      // successful got the data
      console.log(data);
      this.setState({ data });
   });
  }

  render() {
    // failed
    const { data } = this.state;
    return (
      <div>
        <SandkeyGraph
          height={300}
          width={700}
          id="d3-sankey" 
          sankeyData = {this.state.data} 
        />
      </div>
    );
  }
}

export default App;

有人知道如何处理这种情况吗?非常感谢您!

5 个答案:

答案 0 :(得分:2)

解决问题后,事实证明fetch没问题。它只是没有考虑程序中任何组件中的null(使用null值后会崩溃。

例如在渲染中:

render() {
    if (this.state.data) {
      return (
        <div>
          <SandkeyGraph
            height={300}
            width={700}
            id="d3-sankey" 
            sankeyData = {this.state.data} 
          />
        </div>
      );
    }
    else {
      return <div/>
    }
}

或者,使用三元运算符也可以使其更简洁(@Eliran的回答):

return (
  {this.state.data ?
    <div>
      <SandkeyGraph
        height={300}
        width={700}
        id="d3-sankey" 
        sankeyData = {this.state.data} 
      />
    </div> : <div>No Data Available</div>
);

答案 1 :(得分:1)

您可以在渲染函数中添加一个条件:

render() {
// failed
const { data } = this.state;
return (
  <div>
    {data ?
    <SandkeyGraph
      height={300}
      width={700}
      id="d3-sankey" 
      sankeyData={data} 
    /> : "Loading..."
    }
  </div>
);
}

并且仅当填充了数据时,组件才会呈现。

答案 2 :(得分:0)

...
class App extends React.Component {
constructor(props) {
super(props)

  this.state = {
    data : null
  }
}

状态声明似乎出错了?

答案 3 :(得分:0)

1.-像这样在App组件顶部导入json:从'./data/sankey.json'

导入jsonData

2.-在App组件的状态jsonData中设置jsonData。

constructor(props) {
  super(props)
  this.state = {
    jsonData : {}
  }
}

componentWillMount() {
     this.setState({ jsonData })
  }

您不需要在本地获取json时获取。

一旦您的json处于状态,您就可以在渲染器中显示它,例如:

this.state.jsonData.data.links.map(x=>
  <div>
   <div>x.links.source</div>
   <div>x.links.target</div>
  </div>
)

答案 4 :(得分:0)

我一直在测试,您需要将getData()方法替换为此:

  getData = (uri) => {
    fetch(uri, {
      headers : { 
        'Content-Type': 'application/json',
        'Accept': 'application/json'
       }
    })
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      // successful got the data
      console.log(data);
      this.setState({ data });
   });
  }

这是因为您需要在获取选项中声明“ Content-Type”和“ Accept”标头才能发出请求。