list items are not deleting properly (React)

前端 未结 1 1561
刺人心
刺人心 2020-12-02 03:05

I\'d appreciate some help with my note taking app. Let\'s say I have 3 notes on my notes list. I want to delete the note at the top of the list. No matter which one I try to

相关标签:
1条回答
  • 2020-12-02 03:41

    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>

    0 讨论(0)
提交回复
热议问题