title: How to manage state with complex json object in react js
body: <p><strong>Below is the code I have so far, my state isn't working as expected with a bit complex object, I was able to work with a simple object with no nested objects in my state and its working as expected.</strong></p>
  
  <p><strong>state assignment works fine if I don't use personalInfo or contactInfo inside the customer object and used all the properties and create simple customer object</strong></p>
  
  <pre><code>    import React, {PropTypes} from 'react';
      import {Grid,Row,Col,Button,Label} from 'react-bootstrap';
      import {connect} from 'react-redux';
      import * as customerActions from '../../actions/customerActions';
      import {bindActionCreators} from 'redux';
  
      class AddCustomer extends React.Component{
        constructor(props , context){
          super(props , context);
  
      this.state={
        customer:{
          personalInfo:{
            firstName:"",
            lastName:"",
            dob:"",
            ssn:""
  
          },
          contactInfo:{
            address:"",
            addressLine2:"",
            city:"",
            state:"",
            zip:"",
            phoneNumber:"",
            emailAddress:""
          }
        }
      };
      this.handleChange = this.handleChange.bind(this);
      this.onClickCancel = this.onClickCancel.bind(this);
      this.onClickSave = this.onClickSave.bind(this);
    }
  
    handleChange(event) {
      const target = event.target;
      const value = target.type === 'checkbox' ? target.checked : target.value;
      const name = target.name;
      this.setState({
        customer: {
          personalInfo:{
  
          },
          contactInfo:{
  
          },
          ...this.state.customer,
          [name]: value
        }
      });
      console.log(this.state.customer);
    }
  
    onClickCancel(){
  
    }
  
    onClickSave(){
      this.props.actions.createCustomer(this.state.customer);
    }
  
    render() {
      return (
        &lt;div className="container-fluid"&gt;
          &lt;Grid&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={10} md={10}&gt;&lt;b&gt;ADD A LEAD&lt;/b&gt;&lt;/Col&gt;
              &lt;Col xs={2}  md={2}&gt;
                &lt;Button&gt;&amp;times;&lt;/Button&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={12} md={12}&gt;
                &lt;hr/&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;p&gt;&lt;b&gt;Personal Information&lt;/b&gt;&lt;/p&gt;
            &lt;br/&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={6} md={6}&gt;
                &lt;Row&gt;&lt;Label&gt;First Name*&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="personalInfo.firstName" type="text" value={this.state.customer.personalInfo.firstName} onChange={this.handleChange} required="true"/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={6} md={6}&gt;
                &lt;Row&gt;&lt;Label&gt;Last Name*&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="personalInfo.lastName" type="text"  value={this.state.customer.personalInfo.lastName} onChange={this.handleChange} required="true"/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;br/&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={2} md={2}&gt;
                &lt;Row&gt;&lt;Label&gt;Date of Birth*&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="personalInfo.dob" type="text" value={this.state.customer.personalInfo.dob} onChange={this.handleChange} required="true"/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={2} md={2}&gt;
                &lt;Row&gt;&lt;Label&gt;SSN*&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="personalInfo.ssn" type="text"  value={this.state.customer.personalInfo.ssn} onChange={this.handleChange} required="true"/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
  
            &lt;/Row&gt;
            &lt;br/&gt;
            &lt;p&gt;&lt;b&gt;Contact Information&lt;/b&gt;&lt;/p&gt;
            &lt;br/&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={6} md={6}&gt;
                &lt;Row&gt;&lt;Label&gt;Address&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.address" type="text"  value={this.state.customer.contactInfo.address} onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={6} md={6}&gt;
                &lt;Row&gt;&lt;Label&gt;Address Line 2&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.addressLine2" type="text" value={this.state.customer.contactInfo.addressLine2} onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;br/&gt;
  
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={2} md={2}&gt;
                &lt;Row&gt;&lt;Label&gt;City&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.city" type="text" value={this.state.customer.contactInfo.city} onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={2} md={2}&gt;
                &lt;Row&gt;&lt;Label&gt;State&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.state" type="text" value={this.state.customer.contactInfo.state}  onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={2} md={2}&gt;
                &lt;Row&gt;&lt;Label&gt;Zip&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.zip" type="text"  value={this.state.customer.contactInfo.zip} onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;br/&gt;
            &lt;Row className="show-grid"&gt;
              &lt;Col xs={4} md={4}&gt;
                &lt;Row&gt;&lt;Label&gt;Phone Number&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.phoneNumber" type="text" value={this.state.customer.contactInfo.phoneNumber}  onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
              &lt;Col xs={4} md={4}&gt;
                &lt;Row&gt;&lt;Label&gt;Email Address&lt;/Label&gt;&lt;/Row&gt;
                &lt;Row&gt;&lt;input name="contactInfo.emailAddress" type="text" value={this.state.customer.contactInfo.emailAddress} onChange={this.handleChange}/&gt;&lt;/Row&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;br/&gt;
            &lt;Row className="show-grid"&gt;
                &lt;hr/&gt;
            &lt;/Row&gt;
            &lt;Row className="show-grid"&gt;
              &lt;input className="pull-right" type="submit" onClick={this.onClickCancel} value="Cancel"/&gt;
              &lt;input className="pull-right" type="submit" bsStyle="primary" onClick={this.onClickSave} value="Add"/&gt;
            &lt;/Row&gt;
          &lt;/Grid&gt;
        &lt;/div&gt;
      );
    }
  }
  AddCustomer.propTypes={
    actions:PropTypes.object.isRequired,
    customer:PropTypes.array.isRequired
  
  };
  
  function mapStateToProps(state, ownProps) {
    return{
      customer:state.customer
    };
  }
  
  function mapDispatchToProps(dispatch) {
    return{
      actions: bindActionCreators(customerActions,dispatch)
    };
  }
  
  export default connect(mapStateToProps,mapDispatchToProps)(AddCustomer);
  </code></pre>