Uncaught TypeError: невозможно прочитать состояние свойства undefined responsejs

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

При утешении отображается следующая ошибка:

Uncaught TypeError: Cannot read property 'state' of undefined reactjs

Код:

export class Login extends Component {
  constructor(props) {
    super(props);
    this.handleChangeEventforSignUp = this.handleChangeEventforSignUp.bind(this);
    this.createNewUserWithEmailPassword = this.createNewUserWithEmailPassword.bind(this);
    this.state = {
      sign_up_details: {
        email: "",
        password: "",
        confirmpassword: "",
        notification: ""
      }
    };
  }
  
    createNewUserWithEmailPassword(event){
    event.preventDefault();
    if ((this.state.sign_up_details.password !== "") && (this.state.sign_up_details.confirmpassword !== "")){
      if (this.state.sign_up_details.password === this.state.sign_up_details.confirmpassword){
        let updateNotification = Object.assign({}, this.state.sign_up_details, {notification: "Password matched"});
        this.setState({
          sign_up_details: updateNotification
        });

        app.auth().createUserWithEmailAndPassword(this.state.sign_up_details.email, this.state.sign_up_details.password)
        .catch(function(error) {
          // Handle Errors here.
          let errorCode = error.code;
          console.info(errorCode);
          let errorMessage = error.message;
          if (errorCode == 'auth/weak-password') {
            let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage});      
            this.setState({
              sign_up_details: notify
            });
          } else {
            // alert(errorMessage);
            let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage});      
            this.setState({
              sign_up_details: notify
            },
            () => {
              console.info(this.state.sign_up_details);
            } );
          }
          console.info(error);
        }).then(
          function(onResolve, onReject){
            console.info(onResolve);
            console.info(onReject);
          }
        );

      }else{
        let notify = Object.assign({}, this.state.sign_up_details, {notification: "Password not matched"});
        this.setState({
          sign_up_details: notify
        });
      }
    }
  }
  
    handleChangeEventforSignUp(event){
    // console.info(event);
    const  target = event.target;
    let emailInput = "";
    let passwordInput = "";
    let confirmpasswordInput = "";
      
    if (target.type === 'email'){
      emailInput = target.value;
      let updateEmail = Object.assign({}, this.state.sign_up_details, {email: emailInput});
      this.setState({
        sign_up_details: updateEmail
      });

    }

    if (target.type === 'password' && target.name === 'password'){
      passwordInput = target.value;
      let updatePassword = Object.assign({}, this.state.sign_up_details, {password: passwordInput});      
      this.setState({
        sign_up_details: updatePassword
      });
    }

    if (target.type === 'password' && target.name === 'confirmpassword'){
      confirmpasswordInput = target.value;
      let updateConfirmpassword = Object.assign({}, this.state.sign_up_details, {confirmpassword: confirmpasswordInput});
      this.setState({
        sign_up_details: updateConfirmpassword
      });
    }
  }
  
  render() {
    
    const { from } = this.props.location.state || { from: { pathname: '/' } }
    //  const { from } = this.props.history.location || { from: { pathname: '/' } }
    
    if (this.state.redirect === true) {
      return <Redirect to = {from} />
    }

    return (
        <div id = "register" class = "container tab-pane fade animated fadeIn">
          <form onSubmit = {this.createNewUserWithEmailPassword} className = "formfield" ref = {(form) => { this.signupForm = form }} method = "post">
              <h1 className = "text-center login-heading pt-2 pb-4"><i className = "fa fa-pencil fa-lg mx-2" ></i> Register</h1>
              {/* <input value = {this.state.sign_up_details.name} onChange = {this.handleChangeEventforSignUp}  className = "form-control input mb-2" name = "name" type = "text" placeholder = "John Doe" />               */}
              <input value = {this.state.sign_up_details.email} onChange = {this.handleChangeEventforSignUp}  className = "form-control input mb-2" name = "email" type = "email" placeholder = "[email protected]" />
              <input value = {this.state.sign_up_details.password} onChange = {this.handleChangeEventforSignUp}  className = "form-control input mb-2" name = "password" type = "password" placeholder = "*******" />
              <input value = {this.state.sign_up_details.confirmpassword} onChange = {this.handleChangeEventforSignUp}  className = "form-control input mb-2" name = "confirmpassword" type = "password" placeholder = "*******" />              
              <p className = "text_ter text_pink">{this.state.sign_up_details.notification !== "" ? this.state.sign_up_details.notification : ""}</p>
              <input type = "submit" className = "btn btn-primary btn-sm btn-block p-2 mt-4 mb-2" value = "Log In"></input>
          </form>
        </div>

     
    )
  }
}

ReactDOM.render(<Login/>, document.getElementById('app'));
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>

<div id = "app"><div>

введите описание изображения здесь

На какой линии вы столкнулись с этой проблемой? Убедитесь, что ваши функции, использующие this, привязаны к классу.

rash.tay 02.04.2018 15:59

Находясь внутри catch, ваш this не ссылается на класс компонента, поэтому он не имеет никакого состояния. Вы должны объявить его вне асинхронного запроса, например, let self = this.state, а затем использовать его.

Ionut 02.04.2018 16:02

отметьте этот ответ Как сделать setState внутри обратного вызова

Mayank Shukla 02.04.2018 16:03

Консоль показывает ошибку на else { // alert(errorMessage); let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage}); this.setState({ sign_up_details: notify }, () => { console.info(this.state.sign_up_details); } ); в этом блоке код

kropani 02.04.2018 16:15

@Ionut Спасибо, пытаюсь

kropani 02.04.2018 16:17

Пожалуйста, прочтите При каких обстоятельствах я могу добавить к своему вопросу «срочно» или другие похожие фразы, чтобы получить более быстрые ответы? - вкратце, это не идеальный способ обращения к волонтерам и, вероятно, контрпродуктивно для получения ответов. Пожалуйста, воздержитесь от добавления этого к своим вопросам.

halfer 02.04.2018 23:54

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

kropani 03.04.2018 11:08
Вот фрагмент отредактированного кода из вопроса.
kropani 03.04.2018 11:09
app.auth().createUserWithEmailAndPassword(this.state.sign_up‌​_details.email, this.state.sign_up_details.password).catch((error) => {let errorCode = error.code; if (errorCode == 'auth/weak-password') {weakPass = error.message;let notify = Object.assign({}, this.state.sign_up_details, {notification: weakPass}); this.setState({sign_up_details: notify});} else {genericError = error.message;let notify = Object.assign({}, this.state.sign_up_details, {notification: genericError});this.setState({sign_up_details: notify});}
kropani 03.04.2018 11:13
Поведение ключевого слова "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) для оценки ваших знаний,...
0
9
962
2

Ответы 2

Кажется, вы используете реактивный маршрутизатор (который дает вам, например, компонент Redirect), но он никогда не импортируется и не включается нигде?

Извините, но перенаправление не является частью этой ошибки. Что-то не так с this.state.signup_details. Это всего лишь фрагмент кода полного приложения. @timotgl

kropani 03.04.2018 10:39

Могу ли я установить состояние конкретного класса в обещаниях? @timotgl

kropani 03.04.2018 10:41

@kropani Попробуйте изменить методы так, чтобы они включали компонент в this.: createNewUserWithEmailPassword = (event) => {} То же самое для других методов.

timotgl 03.04.2018 12:24

Таким образом, эта ошибка эквивалентна написанию undefined.state.

Взгляните на свои обработчики событий, такие как handleChangeEventForSignup(), которые вы неправильно используете в именовании, это не совсем верблюжий случай, у вас есть handleChangeEventforSignup().

Конкретно в отношении этой ошибки, посмотрите на createNewUserWithEmailPassword().

Вы пытались сначала протестировать это, выполнив:

createNewUserWithEmailPassword(event) {
    event.preventDefault();

    console.info(this.state.sign_up_details);
  }

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

JavaScript считает, что внутри вашего createNewUserWithEmailPassword() не равно this, а вместо этого this равно undefined.

Вам необходимо проверить, для чего ключевое слово this используется внутри класса и как значение this определяется внутри функции.

Ваш экземпляр Login должен иметь несколько различных свойств, таких как state, render() и createNewUserWithEmailPassword().

Вы должны иметь возможность ссылаться на ключевое слово this, которое является ссылкой на сам класс.

Итак, вы говорите, дайте мне ссылку на экземпляр Login, внутри которого я пишу код. Это должно дать вам доступ к state, render() и createNewUserWithEmailPassword().

Я бы очистил код примерно так:

class Login extends React.Component {
  state = {
      sign_up_details: {
        email: "",
        password: "",
        confirmpassword: "",
        notification: ""
      }
    };
  }

если вы не используете import React, { Component } from 'react';, но вы не включили это в свой пост, поэтому я сделал React.Component.

Так почему же this работает неправильно внутри createNewUserWithEmailPassword()?

Чтобы понять это, нам нужно хорошее представление о том, как значение this определяется внутри функции.

class Car {
    setDriveSound(){
    this.sound = sound;
  }

  drive() {
    return this.sound;
  }
}

Это просто фиктивный класс, который позволяет нам установить значение, а затем вернуть это значение.

class Car {
    setDriveSound(sound){
    this.sound = sound;
  }

  drive() {
    return this.sound;
  }
}

const car = new Car();
car.setDriveSound('vroom');
car.drive();

Это выведет vroom.

Итак, вот важное правило, которое необходимо понять. Всякий раз, когда мы хотим выяснить, какое значение this будет внутри метода класса, не смотрите на сам метод, посмотрите на то, где вы его вызвали.

В моем примере выше мы смотрим на car.drive();.

Мы находим имя функции, в данном случае drive(), смотрим на точку слева от функции и смотрим на переменную, на которую есть ссылка внутри.

Таким образом, this из return this.sound; внутри метода drive() будет равен переменной car внутри класса Car.

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

Таким образом, когда drive() вызывается на car, this становится равным экземпляру car.

Я создам объект с именем truck, скопирую функцию drive() из экземпляра car и назначу ее объекту грузовика:

const truck = {
    sound: "honk_honk",
    driveMyTruck: car.drive
}

truck.driveMyTruck();

Это вернет honk_honk, потому что truck равен this внутри функции drive().

Последнее эквивалентно выполнению:

drive() {
  return truck.sound;
}

Давайте применим вышеизложенное к тому, что происходит в вашем случае.

Теперь, если я попробую это:

const drive = car.drive;

drive();

Теперь получил бы Cannot read property 'sound' of undefined.

Поэтому, когда обратный вызов передается элементу формы в какой-то момент времени, мы собираемся вызвать createNewUserWithEmailPassword(), а когда он будет вызван, LogincreateNewUserWithEmailPassword не будет.

Вот этот пример:

class Car {
    setDriveSound(sound){
    this.sound = sound;
  }

  drive() {
    return this.sound;
  }
}

const car = new Car();
car.setDriveSound('vroom');

const drive = car.drive;

drive();

это именно то, что вы сделали или что у вас происходит.

Это все еще может сбивать с толку, это непростая концепция для понимания, я тоже очень часто получаю сообщения об ошибках такого типа.

Итак, как бы вы применили то, что я только что объяснил?

Есть несколько способов решить вашу проблему.

Теперь вы добавили метод constructor(props) с super(props), потому что он расширяет React.Component, и вы сделали this.createNewUserWithEmailPassword = this.createNewUserWithEmailPassword.bind(this);

Это должно было привести к созданию новой версии функции, и она должна была быть исправлена ​​с правильным значением this, но это не решило проблему.

Так что попробуйте это:

class Login extends React.Component {
  state = {
      sign_up_details: {
        email: "",
        password: "",
        confirmpassword: "",
        notification: ""
      }
    };

    createNewUserWithEmailPassword = (event) => {
       event.preventDefault();

       console.info(this.state.sign_up_details);
    }
 }

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