0

I'm a beginner to react js and was wondering why the splice() method wasn't working properly for me. My method is here:

removePara = index => {
    let array = [...this.state.paras];
    for (let x = 0; x < this.state.count; x++) {
      try {
        if (array[x].props.id == index) {
          array.splice(x, 1);
        }
      } catch (e) {}
    }
    this.setState({ paras: array });
  };

So I'm passing an index, and if an element's id matches the index, the element is removed. I'v used a try-catch cause not all indexes are there (they might've been deleted through the same function). Here's and image of three elements: enter image description here

I am pressing delete for middle one but this happens: enter image description here

Instead of the second one getting deleted, the last one gets deleted. How do I fix this? I know that my button's onclick works fine. Full code below:

//index.js
const rootElement = document.getElementById("root");

class App extends React.Component {
  state = {
    paras: [],
    count: 0
  };

  addPara = () => {
    this.setState({
      paras: [
        ...this.state.paras,
        <Paragraph id={this.state.count++} remove={this.removePara} />
      ]
    });
  };

  removePara = index => {
    let array = this.state.paras.filter(e => e.props.id !== index);
    this.setState({ paras: array });
  };

  render() {
    return (
      <div>
        {this.state.paras}
        <div className="btn btn-warning" id="add" onClick={this.addPara}>
          Add Paragraph
        </div>
        <div name="count">{this.state.count}</div>
      </div>
    );
  }
}

ReactDOM.render(<App />, rootElement);

//Paragraph.js
class Paragraph extends React.Component {
  render() {
    let style = {
      height: "150px",
      marginBottom: "10px"
    };

    return (
      <div className="paragraph" id={this.props.id}>
        <div className="row">
          <div className="col-sm-11">
            <textarea
              className="form-control"
              name={"paragraph" + this.props.id}
              placeholder="Put Paragraph Here"
              style={style}
              required
            ></textarea>
          </div>
          <div className="col-sm-1">
            <div
              className="btn btn-danger del-rotate"
              onClick={() => this.props.remove(this.props.id)}
            >
              &times;
            </div>
          </div>
        </div>
      </div>
    );
  }
}
<!--index.html-->
<html>

<head>
    <script type="application/javascript" src="../reactjs/react.js"></script>
    <script type="application/javascript" src="../reactjs/react-dom.js"></script>
    <script type="application/javascript" src="../reactjs/babel.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/styles.css">
    <script src="../bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" type="text/css" href="../bootstrap/css/bootstrap.min.css">
    <script type="text/babel" src="Components/Paragraph.js"></script>
    <script type="text/babel" src="index.js"></script>
</head>

<body id="body">
    <div class="container-fluid">
        <br>
        <br>
        <div class="row">
            <div class="col-sm-1"></div>
            <div class="col-sm-10">
                <div align="center">
                    <h1>Write Article</h1>
                </div>
                <br>
                <form action="submit-article.php" method="POST">
                    <input class="form-control input-sm" type="text" placeholder="Enter Title" name="title"
                        style="width: 35%" autofocus required></input>
                    <br>
                    <div id="root"></div>
                    <br>
                    <input class="btn btn-success float-right" type="submit" value="Done">
                </form>
            </div>
        </div>
    </div>
</body>

</html>

But the element which matches the id gets deleted, like in the elements, its not there, but the input of the one that gets deleted just gets into another element. Like in the example above in the pictures

3
  • 1
    The trouble relates to mutating the array while iterating. Use the loop to build a new array. The built in function for that is filter. array = array.filter(e => e.props.id != index) Commented Feb 27, 2020 at 15:32
  • So what should I do exactly? I've built an array, which is a temporary copy of a state variable I've used, called paras Commented Feb 27, 2020 at 15:33
  • The problem is still happening even when I used your code Commented Feb 27, 2020 at 15:37

1 Answer 1

2

Probably the index you're passing is incorrect,

Array.filter would be more appropriate for this kind of task :

removePara = index => {
  let array = this.state.paras.filter(e => e.props.id !== index);
  this.setState({ paras: array });
};
Sign up to request clarification or add additional context in comments.

5 Comments

We even chose "e" for element simultaneously :-) !!
Thanks for the quick reply, but even when I use this, the same thing happens. And I'm really sure that I'm getting my index correct
if you're dead sure you have the right index, then maybe the numbers you're displaying in the pages are incorrect, can you add the code for that please ?
It sure looks like a zero-based array referring to 1-based set of div ids. Not positive how props.id is initialized, so test this idea with this.props.remove(this.props.id-1)
But the element which matches the id gets deleted, like in the elements, its not there, but the input of the one that gets deleted just gets into another element. Like in the example above in the pictures

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.