Как заставить React.js извлекать данные из API в качестве состояния и передавать эти данные состояния от своего родителя дочернему компоненту - PullRequest
0 голосов
/ 16 декабря 2018

Я работаю над проектом React.js + D3.js.Я хотел, чтобы App.js извлекал данные из файла json, сохранял эти данные в состояние и передавал эти родительские данные в состояние моего дочернего компонента через свойство.Я обнаружил, что если я использую статические данные в App.js, то работает нормально, но после выборки из файла json не получилось, потому что данные не могут быть сохранены в свойстве.Мои App.js вот так:

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;

parrt of my выглядит примерно так:

class SankeyGraph extends Component {
  displayName: 'SankeyGraph';

  state = {
    sankeyData : null
  }

  constructor(props) {
    super(props);
    this.state.sankeyData = props.sankeyData || null;
  }

  PropTypes : {
    id : PropTypes.string,
    height: PropTypes.number,
    width: PropTypes.number,
    sankeyData : PropTypes.object,
  }

  componentDidMount () {
     // will be null, if using fetch from App.js
    //console.log(this.state.sankeyData);
    this.setContext();
  }
 //...

Кто-нибудь знает, как справиться с этой ситуацией?Большое вам спасибо за продвинутый!

Ответы [ 5 ]

0 голосов
/ 16 декабря 2018

Я тестировал, и вам нужно заменить метод 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' в вашей выборкеварианты, чтобы сделать ваш запрос.

0 голосов
/ 16 декабря 2018

1.- Импортируйте свой json в компонент приложения сверху таким образом: импортируйте jsonData из './data/sankey.json'

2.- Установите 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>
)
0 голосов
/ 16 декабря 2018
...
class App extends React.Component {
constructor(props) {
super(props)

  this.state = {
    data : null
  }
}

Похоже на ошибку в объявлении состояния?

0 голосов
/ 16 декабря 2018

Вы можете добавить в вашу функцию рендеринга условие:

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

и только при заполнении данных будет отображаться компонент.

0 голосов
/ 16 декабря 2018

После решения проблемы оказалось, что с 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>
);
...