bietkul / react-reactive-form

Angular like reactive forms in React.
MIT License
309 stars 32 forks source link

Form config lost on second render #21

Closed jfbloom22 closed 6 years ago

jfbloom22 commented 6 years ago

The form works great until I do a setState() somewhere which triggers a render. Then the form appears to completely loose it's configuration as if there were 0 fields. I noticed that the form passed from onMount the second and following times had no fields. As you can see in the code below I am setting the form to state, then once it is defined on state, I use that one to set back to this.userForm rather than what is passed from onMont. This is working, but I am not sure if this is the best way or maybe I have something setup wrong?

import {
  FormGenerator,
  AbstractControl
} from 'react-reactive-form';
export default class UserQueueForm extends React.Component<Iprops, Istate> {
  public userForm: AbstractControl;
  constructor(props: Iprops) {
    super(props);
    this.state = {
      queueForm: {}
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.setForm = this.setForm.bind(this);
  }
  setForm = (form: AbstractControl) => {
    if (this.state.queueForm.status) {
      this.userForm = this.state.queueForm;
    } else {
      this.userForm = form;
      this.setState({ queueForm: form });
    }
    this.userForm.meta = {
      handleCancel: this.props.handleCancel,
      loading: false
    };
  };
  render() {
    return (
      <div className="loginForm">
        <form onSubmit={this.handleSubmit} className="user-form">
          <FormGenerator onMount={this.setForm} fieldConfig={fieldConfig} />
        </form>
      </div>
    );
  }
bietkul commented 6 years ago

Hey @jfbloom22, It's hard to understand the issue like this, can you please send a code sandbox link with your use case. It'll be really helpful. Thanks

jfbloom22 commented 6 years ago

I put together a sandbox based on your Simple Form With FormGenerator example. https://codesandbox.io/s/n46owpxr2m

You should see it log setForm twice.

Putting this together helped me track down the culprit. In the render statement I am creating a new fieldConfig object (line 103 in the sandbox). I am doing this because I have a form utility file with some re-usable form configurations. In the component I am adding a few additional form fields.

Solution: I simply moved the creation of the new fieldConfig out of the render statement. Now everything works great!

bietkul commented 6 years ago

Cool, yes that's the solution. You must keep your fieldConfig out of the render function to prevent unnecessary control generation , if you're fieldConfig is not static then you can keep it in a state variable. Never change the reference of fieldConfig, until needed.