qazszszsz
qazszszsz

Reputation: 19

I can't call a function that I've assigned to a element in React

import React from "react";
import shortid from "shortid";

export default class App extends React.Component {
  state = {
    items: [],
    text: ""
  };

  handleTextChange = event => {
    this.setState({
      text: event.target.value
    });
  };

  addItem = event => {
    event.preventDefault();
    const newItem = {
      text: this.state.text,
      key: shortid.generate()
    };
    const newItems = [newItem, ...this.state.items];
    this.setState({
      items: newItems,
      text: ""
    });
  };

  deleteItem = event => {
    event.preventDefault();
    console.log("Can't reach this");
  };

  render() {
    const items = this.state.items.map(function(item) {
      return (
        <li onClick={this.deleteItem} key={item.key}>
          {item.text}
        </li>
      );
    });
    return (
      <div className="appMain">
        <div className="formWrapper">
          <form onSubmit={this.addItem}>
            <input
              placeholder="Enter task: "
              onChange={this.handleTextChange}
              value={this.state.text}
            />
            <button type="submit">Add</button>
          </form>
        </div>
        <div className="listWrapper">
          <ul>{items}</ul>
        </div>
      </div>
    );
  }
}

I'm trying to call the 'deleteItem' function when the elements are clicked. I'm checking this with a console.log inside the function. However it's not reaching that when I click on the element? I know it's probably a simple fix, but I've been stuck on it for a while now. can anyone help?

Upvotes: 0

Views: 57

Answers (2)

uday
uday

Reputation: 1481

The issue is you're using a normal function inside .map which don't have access to component this. So you're onClick is not invoking delete function if you replace with an arrow function it works.

something like this:

const items = this.state.items.map(item => {
      return (
        <li onClick={this.deleteItem} key={item.key}>
          {item.text}
        </li>
      );
    });

and working sample

Upvotes: 1

Mobeen
Mobeen

Reputation: 985

Update your items render code to following:

const items = this.state.items.map(item => {
   return (
     <li onClick={this.deleteItem} key={item.key}>
       {item.text}
     </li>
   );
 });

Notice the change from function to ES6 arrow syntax usage. For your case: this inside function won't be referring to class but map function.

Full code: https://codesandbox.io/s/friendly-hopper-z09d1

Upvotes: 2

Related Questions