Почему моя переменная состояния в ReactJS не отображается и почему она не определена? - PullRequest
0 голосов
/ 13 июля 2020

Начинающий реагировать и JavaScript, так что простите меня, если это простое исправление.

Я получаю данные с сервера и намереваюсь проанализировать ответ и сохранить элементы ответа в массиве который является переменной состояния, так как я хочу использовать варианты состояния для соответствующего обновления страницы.

Проблема, с которой я столкнулся, заключается в том, что при использовании fetch () я могу получить данные с сервера , но, видимо, я не могу правильно использовать setState () для присвоения данных переменной. Я читал, что setState () является асинхронным, поэтому ваша переменная состояния может быть обновлена ​​не сразу, и в этом случае мне интересно, могу ли я отображать приложение всякий раз, когда обновляется моя переменная состояния (массив).

Ниже мой код:

import React, { Component } from 'react';
import './App.css';

class App extends Component{
  constructor(props)  {
    super(props);
    this.state = { 
      apiResponse: []
    }; 
    this.getData = this.getData.bind(this);
  }
  componentDidMount() {
    this.getData();
  }

  getData = () => {
    fetch('http://localhost:5000')
      .then(results => results.json())
      .then(console.log)
      .then(results => this.setState({apiResponse: results}, () => {
        console.log('data in state', this.state.apiResponse)
      }))
      .catch(err => console.error(err));
  }
  render()  {
    return (
      <div className="App">
        <h1>Display</h1>
        <h1>{this.state.apiResponse}</h1>
        <h1>Does this work?</h1>
      </div>
    );
  }
}

export default App;

Первый console.log, который я запускаю после fetch, возвращает соответствующий объект JSON, однако следующий console.log после возвращает undefined, а {this.state.apiResponse} не отображает что угодно.

Ответы [ 5 ]

1 голос
/ 13 июля 2020

Проблема в том, что когда вы передаете в качестве обратного вызова функции then consol.log и после того, что вы продолжаете с цепочкой then и ожидаете получить доступ к результату, вы должны, кстати, вызвать прямой вызов цепочка then, в которой вы устанавливаете state перед вызовом на console.log, а затем возвращаете results в этом обратном вызове, например,

fetch('http://localhost:5000')
  .then(results => results.json()) 
  .then(results => {
      this.setState({apiResponse: results}, () => {
          console.log('data in state', this.state.apiResponse)
      });
      return result;
   })
   .then(console.log);

Или просто заменяете его нормальной функцией, подобной этой

fetch('http://localhost:5000')
  .then(results => results.json())
  .then((results) => {
      console.log(results);
      return results;
  })
  .then(results => {
      this.setState({apiResponse: results}, () => {
          console.log('data in state', this.state.apiResponse)
      });
      return result;
   });
1 голос
/ 13 июля 2020

Вы обрабатываете объект json с помощью метода then, но затем вы не возвращаете что-то, чтобы следующий then имел в качестве входных данных.

Если вы удалите эту строку

.then(console.log)

тогда должно работать.

0 голосов
/ 13 июля 2020
    import React, { Component } from 'react';
    import './App.css';
    
    class App extends Component{
      constructor(props)  {
        super(props);
        this.state = { 
          apiResponse: []
        }; 
        this.getData = this.getData.bind(this);
      }
      componentDidMount() {
        this.getData();
      }
    
      getData = () => {
        fetch('http://localhost:5000')
          .then(results => results.json())
          .then(console.log)
          .then(results => this.setState({apiResponse: results}))
          .catch(err => console.error(err));
      }
      render()  {
        return (
          <div className="App">
            <h1>Display</h1>
            <h1>{this.state.apiResponse && 
         this.state.apiResponse.recordSets.map((singleRecord, index)=>           
  singleRecord.map(singleElement => <span> 
              {singleElement.FactoryName}</span>))}</h1>
                <h1>Does this work?</h1>
              </div>
            );
      }
    }
    
    export default App;
0 голосов
/ 13 июля 2020

Это проблема в вашей цепочке , вот ответ:

Метод then возвращает обещание, которое позволяет объединить методы.

Если функция прошла как обработчик, который затем возвращает обещание, эквивалентное обещание будет представлено последующему затем в цепочке методов. - MDN

...
      .then(console.log) // here you're not exposing any response
...
  }

Средство устранения может быть:

...
getData = () => {
    fetch('http://localhost:5000')
      .then(results => {console.log(results); return results.json()})
      .then(results => this.setState({apiResponse: results}, () => {
        console.log('data in state', this.state.apiResponse)
      }))
      .catch(err => console.error(err));
  }
...

0 голосов
/ 13 июля 2020

всякий раз, когда вы разрешаете Promise с помощью .then (), вы хотите передать разрешение следующему обратному вызову. .then(console.log) ломает это. У вас нет результатов в следующем обратном вызове. Подробнее об этом здесь .

...