MalikBagwala
7/19/2019 - 12:53 PM

VesatoGo

VesatoGo

I use react-table npm package and i store all the data required by the table in the state

componentDidMount() {
    this.props.client
      .query({
        query: ALL_SKUS
      })
      .then(({ data }) => {
        const skus = removeTypename(data.allSkuTypes);
        const newData = skus.map((sku, index) => ({
          serial: index + 1,
          ...sku
        }));
        this.setState({ data: newData });
      })
      .catch(err => {
        console.log(err);
      });
  }

this is how the 'name' field of my column looks like

 {
        Header: 'SKU Name',
        headerClassName: 'vt-table-header',
        accessor: 'name',
        maxWidth: 350,
        Cell: this.renderEditable
      },

where this is the event handler

 renderEditable = ({ index, column }) => {
    const { data } = this.state;

    return (
      <InputGroup
        onChange={e => {
          const newData = [...data];
          newData[index][column.id] = e.target.value;
          this.setState({ data: newData });
        }}
        value={data[index][column.id]}
      />
    );
  };

finally this is how all that data goes in the react table

<ReactTable
          loading={data.length === 0 ? true : false}
          showPagination={false}
          className="mt-3 text-center"
          data={data}
          columns={columns}
        />

I have a complex form setup of registering a vehicle the parent object looks something like this

vehicle{
  registrationNumber: "MH1234",
  type: "xyz"
  driver:{
    user:{
      firstName: xyz,
      lastName: abc,
      email: xyz,
      phone: 1234,
      city: random
    },
    kyc:{
      method:xyz,
      id: abcd
    },
  },
  owner:{
    user:{
      firstName: xyz,
      lastName: abc,
      email: xyz,
      phone: 1234,
      city: random
    },
    kyc:{
      method:xyz,
      id: abcd
    },
  }
}

Component Heirarchy

The component heirarchy looks something like this

VehicleRegistration

  • Stores the entire state of the form in the above object and passes it down to the children as props

it has the following children

  • VehicleDetails - stores the information about the vehicle

  • OwnerDetails - stores the information about the owner

    • UserDetails - stores the user part of owner
    • KycDetails - stores the kyc part of owner
  • DriverDetails - stores the information about the driver

    • UserDetails - stores the user part of driver
    • KycDetails - stores the kyc part of driver

how should i approach state management of such a form right now i pass the onChange functions as props to the parent and the parent state is changed on every keyStroke which is an issue to the performance as well since the entire form gets re-rendered on every keystroke

I have access to global state management library like apollo-client's cache and redux

below is the code to give you a better understanding of the flow

<VehicleOwner
  onChange={(owner, error) => {
    const { errors } = this.state;
    errors.owner = error;
    this.setState({
      owner,
      errors,
      isSubmitable:
        countLeaves(err) === 0 &&
        countLeaves(owner) > 0 &&
        countLeaves(driver) > 0 &&
        countLeaves(vehicle) > 0
          ? true
          : false
    });
  }}
  owner={this.state.owner || {}}
  errors={this.state.errors.owner || {}}
/>

inside the owner:

 <UserDetails
  getUserDetails={(user, error) => {
    const { owner, errors, onChange } = { ...this.props };
    owner.user = user;
    errors.user = error;
    onChange(owner, errors);
  }}
  values={this.props.owner.user || {}}
  errors={this.props.errors.user || {}}
/>

<KycDetails
  onChange={(kyc, error) => {
    const { owner, errors } = this.props;
    owner.kyc = kyc;
    errors.kyc = error;
    this.props.onChange(owner, errors);
  }}
  values={this.props.owner.kyc || {}}
  errors={this.props.errors.kyc || {}}
/>

 <LicenceDetails
  onChange={(licence, error) => {
    const { owner, errors } = this.props;
    owner.licence = licence;
    errors.licence = error;
    this.props.onChange(owner, errors);
  }}
  values={this.props.owner.licence || {}}
  errors={this.props.errors.licence || {}}
/>


and finally inside one of these components is individual textinputs which are a wrapper around html input

 <TextInput
  name="idNumber"
  label="licence Number"
  labelInfo="*"
  helperText={errors.idNumber || ''}
  intent={errors.idNumber && 'danger'}
  onInputChange={this.handleInput}
  value={values.idNumber}
/>

Any help will be greatly appreciated