React TypeError: «_this2.setState не является функцией»?

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

Ситуация:

У меня есть класс textinput, в котором у меня есть простая форма для ввода имени пользователем. Когда пользователь отправляет кнопку, вызывается REST-вызов моей серверной части, и пользовательский интерфейс должен отображать имя пользователя.

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

Но когда я звоню из своего класса TextInput, я получаю сообщение об ошибке:

this2.setState is not a function

Я считаю, что это происходит потому, что я вызываю функцию из другого класса, а this state настроен неправильно. Я пытался связать все, но это ничего не меняло. Если у кого-то есть представление о том, что я делаю неправильно, это было бы очень полезно!

У меня есть следующие занятия:

import React, { Component } from 'react';
import logo from './logo.svg';
import Greeting from './components/greeting';
import TextInput from './components/textInput';
import './App.css';

const axios = require('axios');

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {name: "World"};
    this.getFormattedNameFromBackend.bind(this);
    this.setState.bind(this);
  }

  componentDidMount() {
    this.getFormattedNameFromBackend(this.state.name);
  }

  getFormattedNameFromBackend(name) {
    axios({
      method:'get',
      url:'http://localhost:8080/hello?name=' + name
    }).then((response) => {
      this.setState({ name : response.data.name});
    }).catch(function(error){
      console.info(error);
    });
  }


  render() {
    return (
      <div className = "App">
        <header className = "App-header">
          <img src = {logo} className = "App-logo" alt = "logo" />
          <Greeting data = {this.state}/>
          <TextInput callBack = {this.getFormattedNameFromBackend}/>
        </header>
      </div>
    );
  }

}

export default App;

Это основной класс, в котором я получаю ошибку при вызове отдыха axios.

второй класс таков:

import React, { Component } from 'react';

export default class TextInput extends Component {
    constructor(props) {
      super(props);
      this.state = {value: ''};

      this.handleChangeEvent = this.handleChangeEvent.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChangeEvent(event) {
      this.setState({value: event.target.value});
    }

    handleSubmit(event) {
      this.props.callBack(this.state.value);

      event.preventDefault();
    }

    render() {
      return (
        <form onSubmit= {this.handleSubmit}>
          <label>
            Name:
            <input type = "text" value = {this.state.value} onChange = {this.handleChangeEvent} />
          </label>
          <input type = "submit" value = "Submit" />
        </form>
      );
    }
  }

Итак, вопрос в том, как мне правильно вызвать это в методе getFormattedNameFromBackend?

Решено:

ошибка заключалась в неправильной установке реквизита Textinputfield. Правильно должно быть

<TextInput callBack = {(name)=>this.getFormattedNameFromBackend(name)}/>

Похоже, this ссылается не на тот объект. Попробуйте распечатать, что такое this там, где он возникает, или прочитать этот stackoverflow.com/questions/45041878/closures-in-react Короче говоря, события в функции рендеринга действуют на объекты event, а не на класс, для которого определена функция рендеринга, потому что события асинхронны ...

Daniel Dubovski 11.11.2018 14:56

в то время, когда я получаю сообщение об ошибке, это объект типа textinput. Но как мне это изменить?

Marcus Lanvers 11.11.2018 14:58

Попробуйте посмотреть ссылку, которую я предоставил, проще всего привязать ее через закрытие onSubmit= (e) => {this.handleSubmit(e)}. Взгляните и на это: responsejs.org/docs/handling-events.html

Daniel Dubovski 11.11.2018 14:59

Я пытаюсь это сделать, но на самом деле у меня возникают синтаксические ошибки. : / Сейчас я пробую это: onSubmit = {(e) => this.handleSubmit (e)}, но это дает мне ту же ошибку, что и раньше

Marcus Lanvers 11.11.2018 15:03

взгляните на это, вроде работает jsfiddle.net/n5u2wwjg/233958

Daniel Dubovski 11.11.2018 15:18

Большое спасибо, ошибка была "<TextInput callBack = {(name) => this.getFormattedNameFromBackend (name)} />", я искал не в том направлении TT. Вы мне очень помогли, спасибо

Marcus Lanvers 11.11.2018 15:23

Добавлен ответ для других, интересующихся этим. не стесняйтесь отмечать это как решенное!

Daniel Dubovski 11.11.2018 15:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
7
3 713
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если кто-то еще задаст этот вопрос, https://reactjs.org/docs/handling-events.html довольно хорошо объясняет, почему это происходит.

Короче говоря, this не привязан, когда вызываются обратные вызовы событий.

Самый простой способ исправить это - заключить это: onSubmit = {(e) => {this.handleSubmit(e)} (хотя при этом каждый раз создается новый экземпляр функции, поэтому следует соблюдать осторожность при использовании этого метода).

То, как вы это решили, работает, просто избегая привязки, если this вообще, но ваша первоначальная проблема заключалась в том, что строка

    this.getFormattedNameFromBackend.bind(this);

не делает именно то, что вы думаете. .bind() возвращает новую функцию, которая обертывает исходную функцию, но вы ничего не делаете с этой новой функцией. .bind() не изменяет исходную функцию, поэтому this.getFormattedNameFromBackend остается несвязанным, и поэтому <TextInput callBack = {this.getFormattedNameFromBackend}/> не работает.

Если бы вы написали эту строку как:

    this.getFormattedNameFromBackend = this.getFormattedNameFromBackend.bind(this);

... (как вы это делаете в своем классе TextInput) он будет правильно привязан, и callBack = {this.getFormattedNameFromBackend} будет работать.

Как я уже сказал, записывая его как callBack = {() => this.getFormattedNameFromBackend()}, вы в любом случае избегаете проблемы привязки, поэтому вы можете просто удалить this.getFormattedNameFromBackend.bind(this); (и, кстати, this.setState.bind(this); тоже довольно бессмысленный)

Другие вопросы по теме