P
P
Proroks2017-06-08 18:05:06
React
Proroks, 2017-06-08 18:05:06

Removing an element?

Can you please tell me why it doesn't work? https://codepen.io/anon/pen/awvXRR
You need to click on an element to delete it

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim, 2017-06-08
@Proroks

class App extends React.Component {
  constructor(){
    super();
    this.state ={
      count: [1,2,3,4,5,6,7,8,9]
    }
  }
  removeCount(idx){ // <= здесь было idk (опечатка)
    let newItems = this.state.count;
    newItems.splice(idx, 1);
    this.setState({count: newItems});
  }
  render() {
    const self = this
    const list = this.state.count.map(function(index, i){
      // здесь у вас был не тот this, так как вы используете обычную функцию, а не стрелочную, "this равный компоненту" теряется, чтобы разобраться можете тут сконослить this и self
      return <div key={i} onClick={self.removeCount.bind(self, i)}><p>{index}</p></div>
    })
    return (
      <div className="row">
       {list}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

V
Viktor Storozhenko, 2017-06-10
@montecazazza

If I understand the problem correctly, then you want to bind the element index to the onClick handler. I prefer to do it through closures.
Along the way, I advise you to move bind to the constructor.
By the way, bind can be omitted if you replace the method declaration with arrow syntax, then everything will become much clearer, the method will look like this and, as I said, bind is not needed:

removeCount = (idx) => (/*сюда будет передан event, но он вам типа не нужен*/) => {
  /* тело с this, он будет autobinded */
}

The constructor will also not be needed, you can just write state
class App extends React.Component {
  //constructor(){
  //  super();
  //  this.state ={
  //   count: [1,2,3,4,5,6,7,8,9]
  //  }
  //  this.removeCount = this.removeCount.bind(this)
  //}
  this.state = {
    count: [1,2,3,4,5,6,7,8,9]
  };
  /*...*/
}

But I kept your version.
If you replace the splice method with a non-mutating slice, then the function body will become one line without additional. variables. Hint in code
class App extends React.Component {
  constructor(){
    super();
    this.state ={
      count: [1,2,3,4,5,6,7,8,9]
    }
  this.removeCount = this.removeCount.bind(this)
  }
  removeCount(idx) {
    return function() {
      let newItems = this.state.count;
      newItems.splice(idx, 1);
      this.setState({count: newItems});
      // this.setState({count: this.state.count.slice(/*чо нада*/)});
      // все что выше в методе тогда не нужно
    }
  }
  render() {
    const list = this.state.count.map(function(index, i){
      return (
        <div 
          key={i} 
          onClick={this.removeCount(i)}>
            <p>{index}</p>
        </div>
      );
    })
    return (
      <div className="row">
       {list}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

Well, OK, my version would look like this (typos are possible, I write right here)
class App extends React.Component {
   state ={
     count: [1,2,3,4,5,6,7,8,9]
  }
  removeCount = (idx) => () => {
    this.setState({count: this.state.count.slice(idx, 1)});
  }
  render() {
    return (
      <div className="row">
       {this.state.count.map(i => (
          <div 
            key={i} 
            onClick={this.removeCount(i)}>
              <p>{i}</p>
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question