ReactJS - добавление .then к функции делает «this.state.searchText» недействительным - PullRequest
0 голосов
/ 29 апреля 2020

Используя ax ios, я звоню в Mon go REST API. Однако всякий раз, когда я нажимаю кнопку, к которой я привязал, я получаю эту ошибку:

TypeError: Object(...)(...) is undefined
onSearchButtonPressed
D:/foo/hello-world/src/RecipeBuilder.js:146

> 146 |     search_elastic(this.state.searchText).then({
      | ^  147 | 
  148 |     })
  149 | 

Почему это происходит? Если я вызываю search_elasti c без добавления then, это похоже на работу, однако данные не возвращаются. Еще интереснее, если я удалю инкапсуляцию метода search_elastic и напрямую вставлю кодовый блок axios.get в метод onSearchButtonPressed(), проблем не будет.

Мой класс настроен так:

import React, { Component } from 'react'
import {search_elastic, shell} from './Backend.js'

class RecipeBuilder extends Component {
    constructor(props) {
        super(props);
        this.state = {
            id: '',
            term: '',
            editDisabled: false,
            ingredients: [],
            candidates: [],
            searchText: '',
            searchResults: []
        }
        this.onSearchTextChange = this.onSearchTextChange.bind(this)
        this.onSearchButtonPressed = this.onSearchButtonPressed.bind(this)
    }
    onSearchTextChange(filterText) {
        console.log({filterText})
        this.setState({
            searchText: filterText
        });
    }
    onSearchButtonPressed() {
        search_elastic(this.state.searchText).then(data => {
            //ideally would like to add data from this method to the RecipeBuilder state

        })
    }
    render () {
        return (
            <div className="col-md-12">
                    <SearchBar
                      searchText={this.state.searchText}
                      onSearchTextChange={this.onSearchTextChange}
                      />
                      <button onClick={this.onSearchButtonPressed}>Search</button>
            </div>
            )
    }
}
export default RecipeBuilder

Компонент SearchBar настроен так:

class SearchBar extends Component {
    constructor(props) {
        super(props);
        this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
    }

    handleSearchTextChange(e) {
        this.props.onSearchTextChange(e.target.value);
    }

    render() {
        return (
            <div>
            <form>
                <input
                 type="text"
                 placeholder="Search..."
                 value={this.props.searchText}
                 onChange={this.handleSearchTextChange}
                />
            </form>
            </div>
        );
    }
}

И Backend.js может быть видел здесь:

import axios from 'axios'


export const search_elastic = term => {
    axios
        .get(`api/search/${term}`, {
            headers: { 'Content-type': 'application/json' }
        })
        .then((response) => {
            console.log(response)
            return response
        })
}

export const shell = () => {
    console.log("In shell")

}

Рабочая версия onSearchButtonPressed() (однако я понятия не имею, почему):

    onSearchButtonPressed() {
        axios.get(`api/search/${this.state.searchText}`, {
                headers: { 'Content-type': 'application/json' }
            }).then((response) => {
                //console.log(response)
                if (response != null) { 
                    var data = response["data"]
                    var result = data["result"]
                    var hitsObj = result["hits"]
                    var hitsArray = hitsObj["hits"]
                    this.setState({searchResults: [...hitsArray]})
                    console.log(this.state.searchResults)
                }
                return response
            })
    }

1 Ответ

1 голос
/ 29 апреля 2020

Ваша search_elastic функция ничего не возвращает. Нужно вернуть обещание от axios.get().

// either *return* axios.get or remove the curlies for an implicit arrow function return
export const search_elastic = term => {
  return axios
    .get(`api/search/${term}`, {
      headers: { 'Content-type': 'application/json' }
    })
    .then((response) => {
      console.log(response)
      return response
    })
}
...