2

enter image description hereenter image description hereI am working on a blog page where you can click on a button and open a modal to edit the comment under the post.

On the Post Details Page I have:

openEditCommentModal = (id) => {
    this.setState(() => ({
    editCommentModalOpen: true,
}))
    this.props.fetchCommentById(id)
}

On the edit comment file I have:

const mapStateToProps = state => {
    return {
        initialValues: state.commentContainer.selectedComment
    }
}

So I do two things: 1. open modal 2. call fetchCommentById(id) so that I can update the state.commentContainer.selectedComment

Post Details page is the parent component, and the edit comment form is the child component.

I need to give initialValue to the edit form. The initialValue is the original content of the comment, and then user can edit it.

Weird thing is that when I click the edit button the first time, NO initialValue. It's an empty object. Therefore I have an empty form. When I close the modal and re open it, initialValue is being updated to be the comment I want, and the edit comment form is now having all the original content.

I don't understand why openEditCommentModal cannot update the state the first time. Can anyone help?

==============

Problem solved: In reduxForm, do this:

enableReinitialize : true

On Post Details page:

openEditCommentModal = (id) => {
        this.setState(() => ({
        editCommentModalOpen: true,
    }))
        this.props.fetchCommentById(id)
    }

.........

<Modal
          className='modal'
          overlayClassName='overlay'
          isOpen={editCommentModalOpen}
          onRequestClose={this.closeEditCommentModal}
          contentLabel='Modal'
        >
         <div>
           <EditComment />
           <button onClick={() => this.closeEditCommentModal()}>Close</button>
           </div>
        </Modal>

...............

const mapDispatchToProps = dispatch => {
    return {
        fetchByPostId: id => dispatch(fetchByPostId(id)),
        deleteByPostId: id => dispatch(deleteByPostId(id)),
        deleteByCommentId: id => dispatch(deleteByCommentId(id)),
        vote: (id, option) => dispatch(vote(id, option)),
        fetchComments: id => dispatch(fetchComments(id)),
        fetchCommentById: id => dispatch(fetchCommentById(id))
    };
 };

Edit Comment Component :

import React, { Component } from "react";
import { Field, reduxForm } from 'redux-form'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { fetchCommentById } from '../Actions'
// import { updateComment } from '../Actions'
const randomID = require("random-id")

class EditComment extends Component {


  renderField = (field) => {
    const { meta: { touched, error } }  = field
    const className = `form-group ${ touched && error ? 'has-danger' : '' }`

    return (
      <div className={className}>
        <label>{field.label}</label>
        <input 
          className="form-control"
          type="text"
          {...field.input}
        />
        <div className="text-help">
          {touched ? error : ''}
        </div>
      </div>
    )
  }

  onSubmit = (values) => {
    const id = values.id
    let newValues = {}
    newValues.body = values.body
  //  this.props.updatePost(newValues, id, this.props.history.push(`/post/${id}`) )
  }

  render() {

    console.log('this.props.initialValue', this.props.initialValues)

    if(!this.props.initialValues) {
      return <div></div>
    } 




    const { handleSubmit, categories, id } = this.props

    return (
      <div>
        <h1>Edit Comment</h1>
        <form onSubmit={handleSubmit(this.onSubmit)}>
          <Field
            label="Content"
            name="body"
            component={this.renderField}
          />
          <span>Author: </span><span>{this.props.initialValues.author}  </span>
          <span>Time: </span><span>{this.props.initialValues.timestamp}</span>
          <div>
          <button type="submit">Submit</button> 

          </div>
        </form>
      </div> 
    )
  }
}
const validate = (values) => {
  const errors = {}

  if(!values.title) {
    errors.title = "Enter a title"
  }
  if(!values.category) {
    errors.category = "Enter a category"
  }
  if(!values.content) {
    errors.content = "Enter some content"
  }
  return errors
}

const mapStateToProps = state => {
  return {
    initialValues: state.commentContainer.selectedComment
  }
}


EditComment = reduxForm({
  validate,
  form: 'CommentEditForm',
  enableReinitialize : true
})(EditComment)


export default connect(mapStateToProps, { fetchCommentById })(EditComment)
25
  • what errors you receive in your console? Commented Aug 28, 2017 at 1:10
  • No error at all....When I console.log(this.props.initialValue) on my editComment file, I got an empty object when I clicked edit the first time. Commented Aug 28, 2017 at 1:20
  • If I close the modal and open it again, console.log(this.props.initialValue) will become the comment object I need Commented Aug 28, 2017 at 1:20
  • do you have any http request including in the process? Commented Aug 28, 2017 at 1:21
  • export const fetchCommentById = id => dispatch => { ReadableAPI.getCommentById(id) .then(comment => { dispatch({ type: FETCH_COMMENT_BY_ID, payload: comment }); }) .catch(err => console.log(err)); }; Commented Aug 28, 2017 at 1:44

1 Answer 1

3

I have checked your code and searched for your problem and i have found this answer that you have to enable the initialization of you form to be bind with your data so what you need to do:

EditComment = reduxForm({
  validate,
  form: 'CommentEditForm',
  enableReinitialize : true // you need to add this property
})(EditComment)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.