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 }
. Надеюсь, это поможет кому-то