React this.state undefined?

I follow the beginner tutorial from Pluralsight, in the submit form, the value is passed to the addUser method, and I need to click userName on this.state.users , but I get an error

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

component

 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 
+22
reactjs
source share
5 answers

When you call {this.addUser} , it is called, here this is an instance of your class (component), and therefore it does not give you any error, since the addUser method exists in your scope class, but when you are under the addUser method, you use this to update state , which exist in the scope of the component (component), but you are currently within the addUser method, and therefore it gives you an error, since in the addUser Scope section you have nothing like state, user, etc. d. Therefore, to solve this problem, you need to bind this while you call the addUser method. So your method always knows an instance of this .

So, the final change in your code will look like this: -

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

OR <h / "> You can bind this in the constructor, because this is the place when you should evaluate things, because the constructor methods are called first when the components display the DOM .

So you can do it like this: -

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

And now you can call it the usual way, as you did before: -

 <Form addUser={this.addUser}/> 

I hope this works, and I let you know.

+49
source share

@Vinit Raj's approaches work fine - so I prefer using arrow function syntax like this.

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

Using such an anonymous function, you do not need to bind it anywhere.

+8
source share

If you prefer to use the arrow function, do it. Arrow function syntax as below

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

To prevent this function from being called every time you render or render, you need to

+ Change

 <Form addUser={this.addUser}/> 

to

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

So addUser is called only when the event occurs / is triggered

+1
source share

In your case, declaring your function as a function of the bold arrow, you add context and remove the requirement to be associated with it. This works the same as other solutions, but greatly simplifies both writing and reading. Just change ...

  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) })*/ } 

to ...

 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) })*/ } 

And everything else can remain the same.

+1
source share

I had the same problem, but my problem was trying to access this.state before completing this.state = {... } . this.state = {...this.function1() } is something like this this.state = {...this.function1() } and function1 =() => { a: this.state.b } . Hope this helps someone

0
source share

All Articles