React this.state undefined?

Я следую за начинающим учебником от Pluralsight, в форме submit значение передается в метод addUser, и мне нужно нажать userName на this.state.users, но я получаю ошибку

 App.jsx:14 Uncaught TypeError: Cannot read property 'users' of undefined

компонент

import React from 'react'
import User from 'user'
import Form from 'form'

class Component extends React.Component {
    constructor() {
        super()
        this.state = {
            users: null
        }
    }
    // This is triggered on form submit in different component
    addUser(userName) { 
        console.log(userName) // correctly gives String
        console.log(this.state) // this is undefined
        console.log(this.state.users) // this is the error
        // and so this code doesn't work
        /*this.setState({
            users: this.state.users.concat(userName)
        })*/
    }
    render() {
        return (
            <div>
            <Form addUser={this.addUser}/>
            </div>
            )
    }
}

export default Component

Ответ 1

Когда вы вызываете {this.addUser}, он вызывается, здесь this - это экземпляр вашего класса (компонента), и поэтому он не дает вам никакой ошибки, поскольку метод addUser существует в вашем классе scope, но когда вы находитесь под addUser методом, вы используете this для обновления state, которые существуют в объем компонента (компонента), но в настоящее время вы находитесь в рамках метода addUser, и поэтому он дает вам ошибку, поскольку в разделе addUser Scope у вас нет ничего, как состояние, пользователь и т.д. Поэтому для решения этой проблемы вам нужно привязать this, пока вы вызываете метод addUser. Так что ваш метод всегда знает экземпляр this.

Итак, окончательное изменение в вашем коде будет выглядеть так: -

<Form addUser={this.addUser.bind(this)}/>

ИЛИ <ч/" > Вы можете связать this в конструкторе, потому что это место, когда вы должны инализовать вещи, потому что методы конструктора вызывается сначала, когда компоненты отображают DOM.

Итак, вы можете сделать это следующим образом: -

  constructor(props) {
    super(props);
    this.state = {
        users: null
    }
    this.addUser=this.addUser.bind(this);
}

И теперь вы можете назвать это обычным способом, как вы это делали раньше: -

<Form addUser={this.addUser}/>

Я надеюсь, что это сработает, И я дал вам понять.

Ответ 2

Подходы @Vinit Raj работают отлично - поэтому я предпочитаю использовать синтаксис функции стрелки, как это.

<Form addUser={ () => this.addUser() }/>

Используя такую анонимную функцию, вам не нужно никуда связывать ее.

Ответ 3

Если вы предпочитаете использовать функцию стрелки, сделайте это. Синтаксис функции стрелки, как показано ниже

addUser = event => { 
    const { value }  = event.target;
    console.log("value", value);
}

Чтобы предотвратить вызов этой функции при каждом рендеринге или рендеринге, вам нужно

+ Изменить

<Form addUser={this.addUser}/>

к

<Form addUser={() => this.addUser()}/>

Так что addUser вызывается только тогда, когда событие происходит/запускается

Ответ 4

В вашем случае, объявив свою функцию как функцию жирной стрелки, вы добавляете контекст и убираете требование связываться с этим. Это работает так же, как и другие решения, но значительно упрощает как запись, так и чтение. Просто поменяй...

 addUser(userName) { 
    console.log(userName) // correctly gives String
    console.log(this.state) // this is undefined
    console.log(this.state.users) // this is the error
    // and so this code doesn't work
    /*this.setState({
        users: this.state.users.concat(userName)
    })*/
}

чтобы...

addUser = (userName) => { 
    console.log(userName) // correctly gives String
    console.log(this.state) // this is undefined
    console.log(this.state.users) // this is the error
    // and so this code doesn't work
    /*this.setState({
        users: this.state.users.concat(userName)
    })*/
}

А все остальное может остаться прежним.

Ответ 5

У меня была та же проблема, но моя проблема была в попытке доступа к this.state до завершения this.state = {... }. this.state = {...this.function1() } что-то вроде этого this.state = {...this.function1() } и function1 =() => { a: this.state.b }. Надеюсь, это поможет кому-то