当前位置: 首页 > 面试题库 >

列表项未正确删除(反应)

宋高扬
2023-03-14
问题内容

我希望我的笔记应用程序能为您提供一些帮助。假设我的记事清单上有3个记事。我想删除列表顶部的注释。无论我尝试删除哪一个,始终会首先删除列表最底部的注释。我检查了React控制台,并且处于应用程序组件状态的notes数组表示已正确删除。但实际上,事实并非如此。如何获得它以便删除我选择的确切音符?

    class App extends 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={i}
                                title={note.newTitle}
                                details={note.newDetails}
                                deleteNote={this.deleteHandler.bind(this,note)} 
                            />
                        ))}
                    </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 NoteEntry extends 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>
            )
          }
        }

问题答案:

index用作时发生此错误key。React使用该key属性来跟踪列表中的元素。当您从数组中间删除元素时,索引不会删除自身,而是会重新排列,最后一个索引会消失。这就是为什么数组中的最后一个元素总是被删除的原因。

对于此解决方案,我提供title的注释为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>


 类似资料:
  • 我正在用AppWidgetHostViews填充RecyclerView。它们被排序一个比一个低,每个都有删除按钮旁边。这就是我如何设置RecyclerView和适配器(Event.Object是AppWidgetHostView): 这是保存AppWidgetHostViews的适配器: 因此它再次为适配器设置数据并通知数据集已更改。 但问题是,当我单击“删除”按钮时,项目没有被正确删除。Vie

  • 我有一个我正在开发的网站:http://designs.totaleeyou.com/rnresources/.在主菜单项上,我有一个li:hover:after效果(一个悬停在li项上方的小饰物)。然而,这种悬停效应只适用于属于导航丸类div的li,而不适用于任何导航丸li。此外,li悬停在页眉处应为蓝色,在页脚处应为白色,但悬停效果仅将白色应用于两者,但当li处于活动状态时,将应用正确的颜色。

  • 问题内容: 在遍历列表时,我想根据条件删除列表中的项。请参见下面的代码。 这给了我一个例外。 如何才能做到这一点? 问题答案: 您需要使用和调用上,而不是使用循环。

  • dart:core库中List类支持的以下函数可用于删除List中的项目。 List.remove() List.remove()函数删除列表中第一次出现的指定项。 如果从列表中删除指定的值,则此函数返回true。 语法 (Syntax) List.remove(Object value) Where, value - 表示应从列表中删除的项的值。 以下example显示如何使用此功能 - vo

  • 编写适当删除双链接列表中由(数据值14)指向的节点的代码片段。 我想我知道如何做到这一点: (1)使右侧的节点的元素指向左侧的节点 (2)使左侧的节点的元素指向右侧的节点 (3) 将指向NULL的节点元素设置为NULL并将其删除。 但是我忘记了如何用代码写这个(已经有一段时间了)。我在想它会是这样的(我假设节点是一个结构,它保存一个int数据,节点*下一个,节点*上一个): 编写代码片段以插入介于

  • 问题内容: 我在Python中有一个列表列表: 我想从中删除重复的元素。如果这是正常列表,而不是我可以使用的列表set。但不幸的是,该列表不可散列,因此无法建立一组列表。只有元组。因此,我可以将所有列表转换为元组,然后使用set并返回列表。但这不是很快。 如何以最有效的方式做到这一点? 上面的结果应为: 我不在乎保留订单。 注意:这个问题很相似,但不是我所需要的。搜索了SO,但没有找到确切的重复项