1

I'm very new to JS and React and coding in general. I'm trying to remove an item from an array using onClick, like so:

const { Component } = React;


class Board extends Component{
  constructor(props) {
    super(props);
    this.state = {
    comments: [
        'I like Rosie',
        'I like you',
        'I like bacon',
        'lalalala'
      ],
    }
  }

  removeComment = (e) =>{

    var filteredArray = this.state.comments.filter(item => item !== e.target.value)
    this.setState({comments: filteredArray});
    console.log(e.target.value)
  }

  eachComment = (text, i) => {
    return ( <p id={i} key={i} > comment: {text} {i}</p> )
  }

  render(){
     console.log('render');
    return (
      <div className="gif-list" onClick={this.removeComment}>
        {this.state.comments.map(this.eachComment)}
      </div>
    );
  }


}



ReactDOM.render(
  <Board/>,
  document.querySelector('#mount'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="mount"><div>

Not much is happening though. My console.log(e.target.value) comes back as undefined. What am I doing wrong?

I have tried looking at other answers but implementing (to me) abstract solutions to other similar problems is not working for me.

Thanks in advance, and apologies for such a simple question.

1
  • a <div> doesn't have a value. Commented Mar 10, 2020 at 17:00

2 Answers 2

2

The div you have the event handler on does not have a value attribute. But even if it did I don't think it will do what you want.

You'll need to change your code a bit in order to get it working like you want:

class Board extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
    comments: [
        'I like Rosie',
        'I like you',
        'I like bacon',
        'lalalala'
      ],
    }
  }

  removeComment = (e) =>{
    // Check the index in the filter to see if it should be kept or removed
    var filteredArray = this.state.comments.filter((item, i) => i != e.target.id)
    this.setState({comments: filteredArray});
    console.log(e.target.id)
  }

  eachComment = (text, i) => {
    // Move the event handler to be on each item
    return ( <p id={i} key={i}  onClick={this.removeComment}> comment: {text} {i}</p> )
  }

  render(){
    return (
      <div className="gif-list">
        {this.state.comments.map(this.eachComment)}
      </div>
    );

  }
}

ReactDOM.render(<Board />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

You'll notice the important changes are:

  1. Give the remove handler to each mapped element
  2. Use an attribute from the event target that actually exists and can be used to determine which element should be removed.
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a bunch! This works :). I guess you don't need to have event handlers in the render function? As long as the state is changed render() is called anyway?
Updates to state will cause a re-render, yes. It doesn't matter where the state update originates from.
Thanks again. I had not expected an answer this quickly!
0

For this one you need to specifically pass in the param when you bind the onClick function


    return (
      <div className="gif-list" onClick={(e)=>this.removeComment(e)}>
        {this.state.comments.map(this.eachComment)}
      </div>
    );

1 Comment

onClick={(e)=>this.removeComment(e)} is effectively the same as onClick={this.removeComment}. The only difference is the first method creates a new anonymous function every render (slightly less efficient).

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.