0

I'm stuck on my note taking app. Basically the App component passes in data to the NoteEntry component through props. Yet I can't figure out how to edit the previous passed text through props within each NoteEntry instance when I click the "edit" button. The edit button is supposed to bring up text inputs to change the content by updating the text and then pressing the save button. Any tips on how to go about it?

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>
    )
  }
}
iagowp
  • 2,428
  • 1
  • 21
  • 32
envincebal
  • 205
  • 1
  • 2
  • 12
  • set the props to the local state once and then change the state on edit text – Yash Sharma Mar 30 '18 at 06:17
  • Possible Duplicate of [how-to-pass-data-from-child-component-to-its-parent-in-reactjs](https://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs/38397755#38397755) – Shubham Khatri Mar 30 '18 at 06:36

1 Answers1

0

You can do by pass data from child to parent component as mention it in comment.

In you case NoteEntry add onEditNote props. This props use for function by parent (App component) and use by onClick edit button.

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

then in class NoteEntry

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

So, handleClickEdit handle by App component and set it to your state

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

Now, your NoteForm component able to edit.

hendrathings
  • 3,720
  • 16
  • 30