data-driven-forms / react-forms

React library for rendering forms.
https://data-driven-forms.org/
Apache License 2.0
302 stars 87 forks source link

Reload form on input change , When Typing in input and save data in state then form getting reload #1431

Closed anjalikalsariya closed 9 months ago

anjalikalsariya commented 9 months ago

Here is code:

import componentMapper from '@data-driven-forms/ant-component-mapper/component-mapper';
import { FormRenderer, useFormApi } from '@data-driven-forms/react-form-renderer';
import { Form, Skeleton } from 'antd';
import React, { useEffect, useState } from 'react';
import { Card } from '@/components/common';
import { BgButton } from '@/components/common/buttons';

const DynamicForm = (props) => {
  const [values, saveFormData] = useState({});

  const setData = (data) => {
    saveFormData('details', data);
  };

  const CustomFormTemplate = ({ formFields }: { formFields: any; schema: any }) => {
    const { handleSubmit, getState, reset } = useFormApi();
    const { submitting, valid } = getState();

    const handleFormOnChange = () => {
      setData(getState().values);
    };

    return (
      <Card
        topLineColor="teal"
        bordered={false}
        addShadow={true}
      >
        <Form
          name="formAntibiotics"
          form={formAntibiotics}
          onSubmitCapture={handleSubmit}
          className="data-form"
          onChange={(e) => handleFormOnChange(e)}
        >
          {formFields}

          <BgButton
            disabled={submitting}
            className="mr-10 m-t-25 text-white"
            bgColor="blue"
            size="middle"
            long={true}
            htmlType="submit"
          >
            {getLabelText('text.validate')}
          </BgButton>
        </Form>
      </Card>
    );
  };

  return (
    <div>
      {schema. fields.length > 0 ? (
        <FormRenderer
          schema={schema}
          onSubmit={(values) => console.log(values)}
          FormTemplate={CustomFormTemplate}
          componentMapper={componentMapper}
          actionMapper={actionMapper}
          subscription={{ values: true }}
        />
      ) : (
        <Skeleton active />
      )}
    </div>
  );
};
rvsia commented 9 months ago

Hello @anjalikalsariya,

I am sorry, I do not understand what is the issue.

Could you please explain it more?

Thanks 😊

Hyperkid123 commented 9 months ago

@anjalikalsariya I think its because the CustomFormTemplate is defined inside the component that manages the state and is "recreated" anytime the parent component re-renders. Either extract the form template outside of the component or memoize it. That should solve the issue.

anjalikalsariya commented 9 months ago

Thanks @Hyperkid123

You are right. Let me try that.

Hyperkid123 commented 9 months ago

If you choose to separate the template, you will have to send custom props to it. Its better to use the child component template for that purpose. You may end up with a similar issue if you modify the FormTemplate prop with an anonymous function. Here is an example:

https://www.data-driven-forms.org/components/children#childrennodeminimalexample

anjalikalsariya commented 9 months ago

Thank you so much @Hyperkid123 .

My issue is fixed by your solution https://www.data-driven-forms.org/components/children#childrennodeminimalexample

anjalikalsariya commented 9 months ago

Hello @anjalikalsariya,

I am sorry, I do not understand what is the issue.

Could you please explain it more?

Thanks 😊

@rvsia That was a reload form issue during every change input. That is fixed now.