2

I use [email protected] in my application. There is some fields where i need to define a validate function dynamically. Note that I need id and slice to look for the correct field in values

<Field
    component={SemanticFormField}
    as={Input}
    placeholder="From"
    name={"participation-card-" + id + "-slice-" + slice + "-min"}
    validate={[number]}
    />
<Field
    component={SemanticFormField}
    as={Input}
    placeholder="to"
    name={"participation-card-" + id + "-slice-" + slice + "-max"}
    validate={[number, validateMaxSlice(slice, id)]}
    />

When i define validateMaxSlice like this

const validateMaxSlice = (slice, id) => (value, values) => {
    const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
    return min >= value ? "Invalid slice" : undefined;
};

Or inline like this

validate={[number, (value, values) => {
const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
    return min >= value ? "Invalid slice" : undefined;}]

The application goes in an infinite loop the moment it renders the component.

The question is why and how to fix it ?

Edit:

Thank you for your help ! Here is how I implement it

Container part:

createSlice() {
    const id = uuidv4();
    return {
        id,
        validators: (value, values) => {
            const min = values["participation-card-" + this.props.id + "-slice-" + id + "-min"];
            return valSup(value, "Tranche incorrecte")(min);
        },
    };
}

addParticipationSlice() {
    let participationSlices = this.state.participationSlices;

    participationSlices.push(this.createSlice());

    this.setState({
        participationSlices,
    });
}

Scene part:

<Field
    component={SemanticFormField}
    as={Input}
    name={"participation-card-" + id + "-slice-" + slice.id + "-max"}
    size="mini"
    width={7}
    validate={[number, slice.validators]}
/>

1 Answer 1

4

As you are creating validators on the fly, it create a new validator instance every time it redraw.

On the first redraw, React try to validate the value, then redraw to update the view. This, in turn, create a new validate function and change the related props value.

As you change the props to the component, react will trigger a re-render of the Field. Thus causing it to revalidate again, causing again a re-render.

One way to correct it is to generate one and only one version of each callback, reusing functions instances when appropriate.

You can for example store a this.validators associative array then change your function generator to something like this:

validateMaxSlice(slice, id) => {
     if (!this.validators[`${slice}-${id}`]) {
          this.validators[`${slice}-${id}`] = (value, values) => { ...Actual validation code... }
     }
     return this.validators[`${slice}-${id}`]
}

This way, validators are created on the fly but reused where they need to be.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.