在 React 中更新笔记应用程序中的道具

Updating props in note taking app in React

我卡在我的笔记应用程序上了。基本上 App 组件通过 props 将数据传递给 NoteEntry 组件。但是,当我单击 "edit" 按钮时,我无法弄清楚如何通过每个 NoteEntry 实例中的道具编辑先前传递的文本。编辑按钮应该调出文本输入以通过更新文本然后按下保存按钮来更改内容。关于如何去做的任何提示?

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,
      editTitle: this.props.title,
      editDetails: this.props.details,
      editing: false
    }
    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" />
          ) : (
              <h2 className="entry-title">{this.props.title}</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"></textarea>
          ) : (
              <p className="details">{this.props.details}</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>
    )
  }
}

您可以将数据从子组件传递到父组件,如评论中所述。

在你的情况下 NoteEntry 添加 onEditNote 道具。此道具由父级(App 组件)用于功能并由 onClick 编辑按钮使用。

<NoteEntry
  ...
  onEditNote={this.handleClickEdit}
  />

然后在 class NoteEntry

<button className="edit" onClick={() => this.props.handleClickEdit(this.props.title, this.props.detail)}>Edit</button>

因此,handleClickEdit 由 App 组件处理并将其设置为您的状态

handleClickEdit = (_title, _detail) => {
  this.setState({title: _title, details: _detail});
}

现在,您的 NoteForm 组件可以编辑了。