snouck
snouck

Reputation: 135

ReactJS: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state

Hello iam newbie in ReactJS, I'm using a library react-bootstrap4-form-validation to validate my form. From the documentation there are the function that use to reset the form validation. From the documentations there are example to reset the form validation using triggering button onClick, like this. And for a condition, i need to reset the validation, but not when triggering button onClick, but when the props from parent component is change. Because of these needs I also created a function (useCompare) that is used to compare the props received from the parent component.

In short, I want to reset my form, when the props received from the parent component changes, and the code is as shown below.

import React, { useRef } from "react";
import { ValidationForm, TextInput } from 'react-bootstrap4-form-validation';
import { useCompare } from '../../services/compare-props';

function TestForm({ form }) {
  const formRefs = useRef();
  

    const handleSubmit = (e, formData, inputs) => {
        e.preventDefault();
        console.log(formData)
    }

    if ( !useCompare(form) ) {
        resetForm()
    }


  function resetForm() {
    let formRef = formRefs.current;
    formRef != null ? formRef.resetValidationState(true) : null;
  }

    return (
        <div className="row justify-content-center">
            <div className="col-md-6 col-sm-10">
                <div className="shadow-sm p-3 mb-5 bg-white rounded border">
                    <h6>{form.labelForm}</h6>
                    <hr />
                    <ValidationForm  onSubmit={handleSubmit} id="form-test" ref={formRefs}>
                        {form.field.map(function (fields, index) {
                            return (
                                <div className="row form-group mb-1" key={index}>
                                    <div className="col-lg-4 col-sm-4 col-md-4">{fields.label}</div>
                                    <div className="col-lg-8 col-sm-8 col-md-8">
                                        <TextInput
                                            type={fields.type}
                                            className="form-control"
                                            name={fields.name}
                                            autoComplete="off"
                                            required
                                            {...(form.formType == 'add' && fields.name == 'brand_code' ? {minLength : "4"} : {})}
                                        />
                                    </div>
                                </div>
                            );
                        })}
                        <button type="submit" className="btn btn-danger">
                            Save
                        </button>
                        <button type="button" className="btn btn-warning" onClick={() => resetForm()}>
                            Reset Form
                        </button>
                    </ValidationForm>
                </div>
            </div>
        </div>
    );
}

export default TestForm;

The code above works fine when the props received from the parent component doesn't change, and when I try to reset the form via onClick trigger button, it works fine too. But when I want to reset the form when the props of the parent component changes, it generates an error like this:

Warning: Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state

Can anyone help me solve this problem? I am very grateful beforehand.

Upvotes: 4

Views: 3325

Answers (1)

Nick Carbone
Nick Carbone

Reputation: 218

Try moving useCompare check to a side effect:

useEffect( () => {
    if ( !useCompare(form) ) {
        resetForm()
    }
}, [useCompare, form, resetForm] )

You will likely have to wrap resetForm in a useCallback hook.

This useEffect will run every time form changes, and placing it here should prevent the 'update during render' issue.

Upvotes: 4

Related Questions