Chris Hadfield
Chris Hadfield

Reputation: 524

Share form data value from child component to parent component - React js

I have made a common component which served as a parent component. I have made a PageCommonComponent as below.

import { Link } from 'react-router-dom';
import { Component } from 'react';
import ActionType from '../helper/Enum';
import axios from 'axios';
import BaseService from './base-service';

class PageCommon extends Component {
    baseService = new BaseService();

constructor(pros) {
    super(pros);
    this.state = {
        action: pros.action,
        indexPageUrl: pros.indexPageUrl,
        url: pros.url,
        saveData: pros.saveData
    }
}

saveData = () => {
    console.log(this.state.saveData)
    alert('save button clicked')
    
}

modifyData = () => {

}

deleteData = () => {

}

render() {
    let button;

    if (this.state.action === ActionType.Create) {
        button =
            <button type="button" onClick={this.saveData} className="btn btn-primary btn-round">
                <i className="nc-icon nc-simple-add"></i>
                &nbsp; Create
            </button>
    } else if (this.state.action === ActionType.Modify) {
        button =
            <button type="button" onClick={this.modifyData} className="btn btn-primary btn-round">
                <i className="nc-icon nc-simple-update"></i>
                &nbsp; Modify
            </button>
    } else if (this.state.action === ActionType.Delete) {
        button =
            <button type="button" onClick={this.deleteData} className="btn btn-danger btn-round">
                <i className="nc-icon nc-simple-remove"></i>
                &nbsp; Delete
            </button>
    }

    return (
        <div>
            {button}
            <Link className="btn btn-danger btn-round" to={this.state.indexPageUrl}>
                <i className="nc-icon nc-simple-remove"></i>
                &nbsp; Cancel
            </Link>
        </div>
    );
}
}

export default PageCommon;

This component will done all of the crud functionality here. But the value will be passed from another child component call RoleCreate.Here is how I have used this component on another component.

import { Component } from 'react';
import PageCommon from './../../../common/pagecommon';

class RoleCreate extends Component {
    constructor(pros) {
        super(pros);
        this.state = {
            formData: {
                roleName: ''
            }
        }
    }

    handleChange = (postData) => {
        this.setState({ formData: postData });
    }

    render() {
        return (
            <div className="row">
                <form style={{ 'width': '100%' }}>
                    <div className="col-md-12 col-sm-12 col-lg-12 card card-user">
                        <div className="row card-header" style={{ "borderBottom": "1px solid #d0c8c8" }}>
                            <div className="col-md-8">
                                <h5 className="card-title">Role Create</h5>
                            </div>
                            <div className="col-md-4 text-right">
                                <PageCommon
                                    action={this.state.action}
                                    url="/role/create"
                                    indexPageUrl="/role"
                                    saveData={this.state.formData}
                                    onSubmitChild={this.state.formData} />
                            </div>
                        </div>
                        <div className="card-body">
                            <div className="row">
                                <div className="col-md-5 pr-1">
                                    <div class
                                    Name="form-group">
                                        <label>Role Name</label>
                                        <input type="text"
                                            onChange={(e) => this.handleChange({ roleName: e.target.value })}
                                            className="form-control" placeholder="Role Name" />
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        );
    }
}

export default RoleCreate;

I have pass form data via saveData parameter but this doesn't passes the value instead only pass the object of that formData without any value. How can I do this please help me. Thank you.

Upvotes: 1

Views: 227

Answers (1)

Drew Reese
Drew Reese

Reputation: 202801

PageCommon is only saving passed props into state in the constructor when the component is getting ready to mount. The constructor is ran only once in a component's lifecycle.

constructor(props) {
  super(props);
  this.state = {
    action: props.action,
    indexPageUrl: props.indexPageUrl,
    url: props.url,
    saveData: props.saveData
  };
}

After that it doesn't handle receiving updated prop values.

From what I can tell you want to locally cache form data until a user clicks one of the buttons to take some action upon the saved data.

Implement the componentDidUpdate lifecycle method in PageCommon to update local state with the new saveData form data and action values.

componentDidUpdate(prevProps, prevState) {
  // If saved data in state is different than new data from props, update state
  if (prevState.saveData !== this.props.saveData) {
    this.setState({
      action: this.props.action,
      saveData: this.props.saveData,
    });
  }
}

Upvotes: 2

Related Questions