0

I am fairly new to ReactJs and I do have some problems with regards to looping through a JavaScript Array. I have managed to loop it through with no errors but when I add delete button on the each list with an onClick to the removeSkill function I get an error "app.js:59097 Uncaught TypeError: Cannot read property 'removeSkill' of undefined"

No Error

const skillLists = this.state.skills.map(function(val){
                return <li>{val}</li>
            });

With Error

const skillLists = this.state.skills.map(function(val){
                return <li>{val} <button onClick={this.removeSkill}>x</button></li>
            });

Full Code

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Skills extends Component {
    constructor(props) {
        super(props);

        this.state = { 
            skills : ["Frost Bolt", "Arcane Missle"],
            skillField : ''
        };

        this.addSkill = this.addSkill.bind(this);
        this.removeSkill = this.removeSkill.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.clearField = this.clearField.bind(this);
    }

    clearField() {
        this.state.skillField = '';
    }

    handleChange(event) {
        this.setState({
            skillField : event.target.value
        });
    }

    addSkill() {
        this.state.skills.push(this.state.skillField);
        this.setState({
            skills: this.state.skills
        });
        console.log(this.state.skills);
        this.clearField();
    }

    removeSkill() {
        console.log("skillremoved");
    }

    render() {
        const skillLists = this.state.skills.map(function(val){
            return <li>{val} <button onClick={this.removeSkill}>x</button></li>
        });
        return (
            <div>
                <input onChange={this.handleChange} value={this.state.skillField} />
                <button onClick={this.addSkill}>Add Skill</button>
                <h4>Skills</h4>
                <ul>{skillLists}</ul>
            </div>
        );
    }
}

export default Skills;

Any help would be very much appreciated. Thanks!

drake24
  • 525
  • 1
  • 11
  • 32

1 Answers1

2

The problem is that you are not using an arrow function and so you lose the reference to this.

const skillLists = this.state.skills.map(function(val){
        return <li>{val} <button onClick={this.removeSkill}>x</button></li>
    });

Try with an arrow function

const skillLists = this.state.skills.map((val) => {
        return <li>{val} <button onClick={this.removeSkill}>x</button></li>
    });
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • But why!? This is my problem for almost 2 days, using for loop, the value on console.log shows the correct value, but the onclick shows undefined. Making it arrow function solves my problem, thank you! – Julio de Leon Aug 21 '20 at 11:01