question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug with setState in event handlers

See original GitHub issue

Prerequisites

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

Description

There is an App which renders rjsf Form. When you call App’s setState(updates value unrelated with the form's props) in Form.props.onChange then Form loses its internal state.

Steps to Reproduce

  1. Create a stateful component (A) which renders the Form with some simple schema.
  2. In this component (A) create onChange handler which is passed into the Form.
  3. In this handler call setState which updates some value which is not passed into the Form component.
  4. Type something into the input and you’ll see that it immediately removes the typed value.

Here is a reproducible demo.

Expected behavior

Form shouldn’t loose its state.

Actual behavior

Form lost its state.

Version

1.0.4

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:9
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
affan-speridiancommented, Aug 10, 2020

@Leksat hey, thanks for responding. Much appreciated. I just tested it. It works but for a few seconds. I mean it preserves the internal state but as I go along filling the form. After few seconds older one got refreshed…

Here are my code:

form.js

import React from 'react'
import Form from 'react-jsonschema-form';

class FixedForm extends Form {

    constructor(props){
        super(props)
    }

    componentWillReceiveProps(nextProps) {
        const shouldSkipUpdate =
            Object.keys(nextProps).length === Object.keys(this.props).length &&
            Object.keys(nextProps).filter(
                key =>
                    nextProps[key] !== this.props[key]
            ).length === 0;
        if (shouldSkipUpdate) {
            return;
        }
        super.componentWillReceiveProps(nextProps);
    }

    render() {
        return <Form {...this.props}/>
    }
}

export default FixedForm

my custom-form.js in components folder

import React from 'react'
import RForm from './form'

export const Form = (props) => {
  return (
    <RForm {...props} widgets={{
      BaseInput: TextInput,
      CheckboxWidget,
      FileWidget: FileUpload,
      SelectWidget
    }}>
      <Spacer />
      <Button submit type="primary">{props.submitText}</Button>
      <Loader loading={props.loading} />
    </RForm>
  )
}

then in my component where I use it, I do

import { Form } from '../../custom-form'

<Form schema={schema} onSubmit={onSubmit} onChange={onChange} submitText="Add" noValidate={true} loading={loading} />
2reactions
Leksatcommented, Aug 10, 2020

@affan-speridian

import Form from 'react-jsonschema-form';

class FixedForm extends Form {
  componentWillReceiveProps(nextProps) {
    const shouldSkipUpdate =
      Object.keys(nextProps).length === Object.keys(this.props).length &&
      Object.keys(nextProps).filter(
        key =>
          key !== 'children' &&

          // Maybe some other logic.

          nextProps[key] !== this.props[key]
      ).length === 0;
    if (shouldSkipUpdate) {
      return;
    }
    super.componentWillReceiveProps(nextProps);
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't call setState on a component that is not yet mounted ...
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application....
Read more >
Beware: React setState is asynchronous! | by Tomas Carnecky
I recently fixed a bug in one of my applications whose root cause was that I was calling setState multiple times during a...
Read more >
React.Component
setState () enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the...
Read more >
Why React doesn't update state immediately - LogRocket Blog
For this reason, React batches state updates. No matter how many setState() calls are in the handleClick event handler, they will produce only...
Read more >
1075565 - 'afterprint' is not fired and browser is frozen when ...
... is not fired and browser is frozen when react set state is called inside event handler ... There is a video recording...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found