Событие после вызова setState дает мне предыдущее значение состояния - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь создать панель поиска для моего приложения React.js.

Я передал getSearch() метод app.js в навигацию дочерних компонентов для получения входного значения.

В getSearch() методе есть setState({searchTerm:e.target.value}), который является извлеченным значением, и затем я вызываю fetchData() метод app.js сразу после setState() в getSearch().

в fetchData() метод this.state.searchTerm передается как тело для fetch(), но когда я что-то ввожу и нажимаю «Ввод», это дает мне предыдущее значение this.state.searchTerm, а не последнее обновленное значение, которое вводит пользователь.

Что такоеЯ делаю не так?Я добавляю app.js для просмотра:

import React, { Component } from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";

import "./App.css";

import Navigation from "./components/Navigation";
import Sidebar from "./components/Sidebar";
import Game from "./components/games";
import Profile from "./components/Profile";
import NotFound from "./components/Notfound";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      gameFetched: "false",
      searchTerm: ""
    };
  }
  getSearch = e => {
    if (e.key === "Enter") {
      this.setState({
        searchTerm: e.target.value
      });
      this.fetchIGBD()
    }
  };

  componentDidMount() {
    this.fetchIGBD();
  }

  render() {
    return (
      <div className="App">
        <BrowserRouter>
          <div>
            <Navigation getSearch={this.getSearch} />
            <div id="main-wrapper" className="d-flex">
              <Sidebar />
              <div id="content">
                <Switch>
                  <Route path="/" component={Game} exact />
                  <Route path="/profile" component={Profile} />
                  <Route component={NotFound} />
                </Switch>
              </div>
            </div>
          </div>
        </BrowserRouter>
      </div>
    );
  }

  fetchIGBD = () => {
    let url = "http://localhost:8080/api-v3.igdb.com/games";
    let data ="fields name,cover,first_release_date,genres.name,platforms.name,total_rating;limit 10;sort popularity;where total_rating > 80;where release_dates.platform = 6;";
    let search = "search '"+this.state.searchTerm+"';";
    if (search !== "") {
      data = data + search
      console.log(data)
    }
    fetch(url, {
      method: "POST",
      body: data,
      headers: {
        "Content-Type": "application/json",
        "user-key": "myid"
      }
    })
      .then(res => res.json())
      .then(json => console.log(json))
      .catch(error => console.log(error));
    this.setState({
      gameFetched: "true"
    });
  };
}

export default App;

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Вы можете использовать следующее:

this.setState({
  searchTerm: e.target.value
 }, () => { 
  this.fetchIGBD()
});

setState функция асинхронна, что означает, что она не выполняется немедленно.

0 голосов
/ 02 марта 2019

Если вам нужно использовать состояние в вашем методе fetchIGBD, вам нужно вызвать его в параметре callback setState.Это необходимо, потому что setState является асинхронным.

  getSearch = e => {
    if (e.key === "Enter") {
      this.setState({
        searchTerm: e.target.value
      }, this.fetchIGBD);
    }
  };

или если вам нужно передать ему параметры

  getSearch = e => {
    if (e.key === "Enter") {
      this.setState({
        searchTerm: e.target.value
      }, ()=> this.fetchIGBD(params_here));
    }
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...