Reactjs: Using same form for add and update

I think it's better you create separate component for rendering form data(FormComponent) and separate components for edit(EditComponent) and add(AddComponent).

This way there will not be clutter in one component and no if/else conditions for different modes like edit or add, or in future copy mode.

This approach will add flexibility and enhances compositional pattern of react.

1) AddComponent

import React, { Component } from 'react';
import { connect } from 'react-redux'


class AddComponent extends Component {
  handleSubmit = (title, message) => {
    const data = {
      id: new Date(),
      title,
      message,
      editing: false
    }
    this.props.dispatch({
        type: 'ADD_POST',
        data,
    });
  }
    render() {
        return (
            <div>
                <h1>Create Post</h1>
                <FormComponent
                    buttonLabel='Post'
                    handleSubmit={this.handleSubmit}
                />
            </div>
        );
    }
}
export default connect()(AddComponent);

2) EditComponent

import React, { Component } from 'react';
import { connect } from 'react-redux';


class EditComponent extends Component {
    handleSubmit = (newTitle, newMessage) => {
        const data = {
            newTitle,
            newMessage
        }
        this.props.dispatch({ type: 'UPDATE', id: this.props.post.id, data: data })
    }

    render() {
        return (
        <div>
            <FormComponent
                buttonLabel='Update'
                handleSubmit={this.handleSubmit}
            />
        </div>
        );
    }
}
export default connect()(EditComponent);

3) FormComponent

import React, { Component } from 'react';

class FormComponent extends Component {
    handleSubmit = (e) => {
        e.preventDefault();
        const title = this.getTitle.value;
        const message =  this.getMessage.value;
        this.props.handleSubmit(title, message);
    }
    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <input required type="text" ref={(input) => this.getTitle = input}
                defaultValue={this.props.post.title} placeholder="Enter Post Title" /><br /><br />
                <textarea required rows="5" ref={(input) => this.getMessage = input}
                defaultValue={this.props.post.message} cols="28" placeholder="Enter Post" /><br /><br />
                <button>{this.props.buttonLabel}</button>
            </form>
        );
    }
}
export default FormComponent;

Hope that helps!!!


You can create your own Form component with a prop of editMode to control whether it's Create or Update.

import React, {Component} from 'react';
import PropTypes from 'prop-types';

class Form extends Component {
    handleSubmit = e => {
        e.preventDefault();
        const {editMode, post} = this.props;
        const title = this.titleRef.value;
        const body = this.bodyRef.value;
        if (editMode){
            const data = {
                title,
                body
            }
            this.props.dispatch({type: 'UPDATE', id: post.id, data})
        }
        else {
            const data = {
                id: new Date(),
                title,
                message,
                editing: false
            }
            this.props.dispatch({type: 'ADD_POST', data});
        }
    }

    render() {
        const {editMode, post} = this.props;
        const pageTitle = editMode ? 'Edit Post' : 'Create Post';
        const buttonTitle = editMode ? 'Update' : 'Post';
        return (
            <div>
                <h1>{pageTitle}</h1>
                <form onSubmit={this.handleSubmit}>
                    <input
                        required
                        type="text"
                        ref={input => this.titleRef = input}
                        placeholder="Enter Post Title"
                        defaultValue={post.title}
                    />
                    <textarea
                        required
                        rows="5"
                        ref={input => this.bodyRef = input}
                        cols="28"
                        placeholder="Enter Post"
                        defaultValue={post.body}
                    />
                    <button>{buttonTitle}</button>
                </form>
            </div>
        );
    }
}

Form.propTypes = {
    editMode: PropTypes.bool,
    post: PropTypes.object
}

Form.defaultProps = {
    editMode: false,    // false: Create mode, true: Edit mode
    post: {
        title: "",
        body: ""
    }    // Pass defined Post object in create mode in order not to get undefined objects in 'defaultValue's of inputs.
}

export default Form;

It would be on create mode by default but if you wanna update the post you should pass editMode={true} to your form component.

Tags:

Reactjs

Redux