React-jsonschema-form: Form constructor should not call the onChange method

Created on 14 Mar 2020  路  3Comments  路  Source: rjsf-team/react-jsonschema-form

Prerequisites

  • [x] I have read the documentation;
  • [x] In the case of a bug report, I understand that providing a SSCCE example is tremendously useful to the maintainers.

Description

We may have side effect in onChange method, the onChange call in Form constructor will have this warning using the latest ReactJs.

Cannot update a component from inside the function body of a different component.

packages/core/src/components/Form.js

export default class Form extends Component {
  static defaultProps = {
    uiSchema: {},
    noValidate: false,
    liveValidate: false,
    disabled: false,
    noHtml5Validate: false,
    ErrorList: DefaultErrorList,
    omitExtraData: false,
  };

  constructor(props) {
    super(props);
    this.state = this.getStateFromProps(props, props.formData);
    if (
      this.props.onChange &&
      !deepEquals(this.state.formData, this.props.formData)
    ) {
      this.props.onChange(this.state);
    }
    this.formElement = null;
  }

}
bug

Most helpful comment

@epicfaace , I don't need to call onChange in a form's constructor, the above snippet is copied from
packages/core/src/components/Form.js

 constructor(props) {
    super(props);
    this.state = this.getStateFromProps(props, props.formData);
    if (
      this.props.onChange &&
      !deepEquals(this.state.formData, this.props.formData)
    ) {
    // this custom onChange method may have side effect,  for example , call setState method, 
    // a component constructor is called during rendering, 
    // that is why  React comlains 
   //`Cannot update a component from inside the function body of a different component.`
      this.props.onChange(this.state);
    }
    this.formElement = null;
  }

All 3 comments

@videni In what situation would you need to call onChange in a form's constructor (as opposed to componentDidMount)?

I believe that the side effect here is that onChange sets the state, as it has to update the state when validations are performed or data must be omitted.

https://github.com/rjsf-team/react-jsonschema-form/blob/master/packages/core/src/components/Form.js#L176-L227

@epicfaace , I don't need to call onChange in a form's constructor, the above snippet is copied from
packages/core/src/components/Form.js

 constructor(props) {
    super(props);
    this.state = this.getStateFromProps(props, props.formData);
    if (
      this.props.onChange &&
      !deepEquals(this.state.formData, this.props.formData)
    ) {
    // this custom onChange method may have side effect,  for example , call setState method, 
    // a component constructor is called during rendering, 
    // that is why  React comlains 
   //`Cannot update a component from inside the function body of a different component.`
      this.props.onChange(this.state);
    }
    this.formElement = null;
  }

Hi. Great package.

Any sense when this might be addressed, or if there's a quick-n-dirty workaround?

I'm trying to show the state of each field in a form as users type. While I have no problems rendering or submitting the form, I can't seem to get past this exact issue and error.

On this matter, my code boils down to --> onChange={onChange}.

I've tried passing a simple Hooks-based updater, as well as a bound version, structured like the log function in your docs, and innumerable closures as shots in the dark. Sadly, no joy.

Any thoughts appreciated.

Was this page helpful?
0 / 5 - 0 ratings