Can anyone help me with update action in react-rails?

Can anyone help me with update action in react-rails?
0

#1

I am trying to build a simple rails backend and react frontend blog app. Everything was going fine until I get to edit action when I was trying to edit a post. I can not set propTypes and using refs in form. I am getting the following error

[![see the below image link to see the error details][1]][1]


[1]: https://i.stack.imgur.com/VvdS0.png

I am using react-rails gem

here is my controller edit and update actions

def edit
 @post = Post.find(params[:id])
end

def update
 if @post.update(post_params)
  render json: { post: @post }
else
 render :edit
end

end

here edit.html.erb

<%= react_component 'EditPost', { post: @post.as_json(only: [:id, :title, :body]) } %>

and below is the EditPost component which is located in assets/javascripts/components

class EditPost extends React.Component {

  constructor(props) {
    super(props)

  }

  render () {

    return (
      <div className="row">
        <div className="col-md-6 col-md-offset-3">
          <h3>Post</h3>
          <form>
            <div className="form-group">
              <label htmlFor="title">Title</label>
              <input type="text"
                     className="form-control"
                     placeholder="title"
                     ref="title" /> // here I can't set ref
            </div> <br />
            <div className="form-group">
              <label htmlFor="body">Body</label>
              <input type="text"
                     className="form-control"
                     placeholder="body"
                     ref="body" /> // here I can't set ref
            </div> <br />
          </form>
        </div>
      </div>
    )
  }
}
// if I uncomment below code I will get (Uncaught TypeError: can not read property 'string' of undefined
// EditPost.propTypes = {
//   title: React.PropTypes.string.isRequired,
//   body: React.PropTypes.string.isRequired
// }

Here is github repo (https://github.com/Hano1388/react-rails-blog) feel free to clone it to see the error I am getting. Thanks, I appreciate your help


#2

Not familiar with Rails so can’t test, but maybe these will help.



#3

Thanks Implaier. That’s a good resource and those links are shown with the error but, unfortunately they didn’t help solving my issue. May be that’s because I am just a beginner with react. I want to build a full crud react-rails app. If anyone has any tutorial suggestions, that would be helpful. Thanks again Implaier. Your effort to help me is appreciated. May God bless you


#4

Is there any particular reason that you need to use refs in your code, since they are used only in special cases? Otherwise it is much easier to implement a form with as a controlled component.

Here you can read more about forms.


#5

I am getting data from database. I don’t really know the right way to handle the update action.
I need to get the existing post title and body and update them. It’s my first time using react and implementing a crud app. my both get all posts and get a single post actions working just fine but I am stuck here in updating an existing post and I am sure that might happen when I get to (new/create) action.

I changed my form like this. I don’t know what am missing when I handleChange state, I get an error saying that “cannot read property title of undefined”

class EditPost extends React.Component {
 constructor(props) {
  super(props)
  this.state = {
  title: this.props.post.title,
  body: this.props.post.body
 }
 this.handleSubmit = this.handleSubmit.bind(this)
 this.handleChange = this.handleChange.bind(this)
}

handleChange(event) {
 this.setState({
   title: event.target.post.title,  // here where the error is throwing.  "cannot read property title of undefined" 
   body: event.target.post.body,
 })
}

handleSubmit(e) {
 e.preventDefault()
 console.log(this.state)
}

render () {
 const button =
  <button
        type="submit"
        className="btn btn-primary pull-right"
        onClick={this.handleSubmit}>
        Submit
  </button>

return (
  <div className="row">
    <div className="col-md-6 col-md-offset-3">
      <h3>Post</h3>
      <form>
        <div className="form-group">
          <label htmlFor="title">Title</label>
          <input type="text"
                 className="form-control"
                 defaultValue={this.props.post.title}
                 onChange={this.handleChange}
                 // ref="title"
               />
        </div> <br />
        <div className="form-group">
          <label htmlFor="body">Body</label>
          <textarea type="text"
                    rows="8"
                    className="form-control"
                    defaultValue={this.props.post.body}
                    onChange={this.handleChange}
                    // ref="body"
               />
        </div> <br />
        {button}
      </form>
    </div>
  </div>
  )
 }
}

#6

First a correct way to create a controlled component is such:

<input
    name="title"
    type="text"
    className="form-control"
    value={this.state.title}
    onChange={this.handleChange} 
/>

When you use defaultValue the input will use the value for initial rendering but it will not be updated on state change.

You need to add name property to reference this input field later on during onChange event.

As for the handleChange method it can be simplified as such:

handleChange(event) {
    const target = event.target;

    const value = target.value;
    const name = target.name;

    this.setState({
         [name]: value
    });
}

This way you can reuse the method for both form fields by using a computed property name.

Same thing needs to be done for textarea.

Hope this helps.


#7

Thank you Implaier, That helped me handling setState and getting data but, I still have a rails-related issue. that definitely worked to get the data and handling setState. Thank you again, your help is appreciated!