list items are not deleting properly (React)

帅比萌擦擦* 提交于 2019-11-27 09:53:00

This error is occurring from using index as your key. React uses the key attribute to track the elements inside the list. When you are deleting an element from the middle in an array, the index does not delete itself, instead it rearranges and the last index disappears. This is why the last element in your array always got deleted.

For this solution, I have provided title of the note as the key, but this may not be always unique. You will be better using a generated key or a combination of fields as key

class NoteEntry extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      display: false,
      editing: false,
      editTitle: this.props.title,
      editDetails: this.props.details
    }
    this.displayToggle = this.displayToggle.bind(this);
    this.edit = this.edit.bind(this);
    this.save = this.save.bind(this);
  }

  displayToggle() {
    this.setState(prevState => ({
      display: !prevState.display
    }))
  }

  edit() {
    this.setState({
      editing: true
    })
  }

  save() {
    let titleVal = this.refs.updateTitle.value;
    let detailsVal = this.refs.updateDetails.value;
    this.setState({
      editTitle: titleVal,
      editDetails: detailsVal,
      editing: false
    })
  }

  render() {
    return (
      <div className="entry">
        <div className="entry-header" onClick={this.state.editing ? null : this.displayToggle}>
          {this.state.editing ? (
            <input ref="updateTitle" className="edit-title" type="text" defaultValue={this.state.editTitle} />
          ) : (
              <h2 className="entry-title">{this.state.editTitle}</h2>
            )}
          <p className="timestamp">{this.displayTime}</p>
        </div>
        <hr />
        <div className={"entry-content " + (!this.state.display ? "hide-details" : null)}>
          {this.state.editing ? (
            <textarea ref="updateDetails" className="edit-details" cols="10" rows="2" defaultValue={this.state.editDetails}></textarea>
          ) : (
              <p className="details">{this.state.editDetails}</p>
            )}
          <div className="entry-buttons">
            {this.state.editing ? (
              <button className="save" onClick={this.save}>Save</button>
            ) : (
                <button className="edit" onClick={this.edit}>Edit</button>
              )
            }
            <button className="delete" onClick={this.props.deleteNote}>Delete</button>
          </div>
        </div>
      </div>
    )
  }
}

const NoteForm = (props) => {
  return (
    <div>
      <form className="form-section">
        <input
          className="title-input"
          type="type"
          placeholder="Title"
          value={props.titleValue}
          onChange={props.titleHandle}
        />
        <br />
        <textarea
          className="details-input"
          cols="20"
          rows="3"
          placeholder="Details"
          value={props.detailsValue}
          onChange={props.detailsHandle}
          />
        <br />
        <button
          className="input-button"
          onClick={props.onSubmit}>
          Add Note
        </button>
      </form>
    </div>
  )
}


class App extends React.Component {
  constructor(props) {
      super(props);
      this.state = {
          notes: [],
          title: "",
          details: ""
      }
      this.updateTitle = this.updateTitle.bind(this);
      this.updateDetails = this.updateDetails.bind(this);
      this.submitHandler = this.submitHandler.bind(this);
      this.deleteHandler = this.deleteHandler.bind(this);

  }

  updateTitle(event) {
    this.setState({ title: event.target.value });
  }

  updateDetails(event) {
    this.setState({ details: event.target.value });
  }

  submitHandler(e) {
    e.preventDefault();
    if (!this.state.title.length || !this.state.details.length) {
        return;
    }

    const newNote = {
        newTitle: this.state.title,
        newDetails: this.state.details
    }
    this.setState(prevState => ({
        notes: prevState.notes.concat(newNote),
        title: "",
        details: ""
    }))
  }

  deleteHandler(id) {
    this.setState(prevState => ({
        notes: prevState.notes.filter((el)=> el !== id)
    }))
  }

  render() {
    return (
        <div className="container">
            <h1 className="title">React Notes App</h1>
            <NoteForm
                titleValue={this.state.title}
                detailsValue={this.state.details}
                titleHandle={this.updateTitle}
                detailsHandle={this.updateDetails}
                onSubmit={this.submitHandler}
            />
            <div className="entry-section">
                {this.state.notes.map((note,i) => (
                    <NoteEntry
                        key={note.newTitle}
                        title={note.newTitle}
                        details={note.newDetails}
                        deleteNote={this.deleteHandler.bind(this,note)} 
                    />
                ))}
            </div>
        </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!