0

Say I have a render function that looks like this:

  render() {


    var user_rows = []
    this.state.user_list.forEach(function (user, index){
        user_rows.push(
              <tr key={user}>
              <td><div className="btn-toolbar"><button type="button" onClick={this.editUser.(usesr.sso)} className="btn btn-success-outline">Edit</button></div></td>
            </tr>)
    }) 

return (<tbody>
        {user_rows}
      </tbody>)

I get the error:

Uncaught TypeError: Cannot read property 'editUser' of undefined

I would like like the onClick to:

1. Not run when the component is created, only run when actually clicked

2. bind to the function within this component properly

I tried: onClick={this.editUser.bind(null, user.sso)}, but didn't seem to work in this case.

1 Answer 1

3

The problem that you're facing as that the value of this inside of the callback passed to .forEach is not pointing to your React component class, but rather the global object.

Possible solutions:

1) Pass the correct value of this as the second argument to .forEach.

this.state.user_list.forEach(function (user, index) {
    // your code
}, this);

2) If you're using ES6, use an arrow function as your first argument to .forEach, which will automatically use the correct context.

this.state.user_list.forEach((user, index) => {
    // your code
});

An alternate approach to this problem would be to use the .map function to map each value in your array to some JSX that can be used in your render() function.

const user_rows = this.state.user_list.map(user => 
     <tr key={user}>
         <td>
             <div className="btn-toolbar">
                 <button type="button" onClick={this.edituser[user.sso]} className="btn btn-success-outline">Edit</button>
             </div>
         </td>
     </tr>
);
Sign up to request clarification or add additional context in comments.

3 Comments

Just a side note: Instead of declaring a variable user_rows as an empty array and filling it using .forEach, you can achieve the same result using .map instead. If you're curious as to how this would work, I can edit my answer to include a code snippet.
Hey Michael, that would be very useful to include! Thanks!
@ApathyBear Done! Let me know if this doesn't make sense and I can try and clarify further.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.