Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use useComputed inside useMemo hook?

During development Eslint prompted me with this information:

The ‘fields’ object makes the dependencies of useCallback Hook (at line 183) change on every render. Move it inside the useCallback callback. Alternatively, wrap the initialization of ‘fields’ in its own useMemo() Hook

Code looks like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const fields: { [p: string]: EntityField } = {
        'Kredieten': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.kredieten.id), [metadataService]),
        'Deelnemingen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.deelnemingen.id), [metadataService]),
        'Toeleveranciers': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.toeleveranciers.id), [metadataService]),
        'Vervoersmiddelen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.vervoersmiddelen.id), [metadataService]),
        'Liquide middelen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.liquideMiddelen.id), [metadataService]),
        'Voorraden': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.voorraden.id), [metadataService]),
        'Groepsvermogen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.groepsvermogen.id), [metadataService]),
        'Gebouwen en terreinen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.gebouwenEnTerreinen.id), [metadataService]),
        'Machines & Installaties': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.machinesAndInstallaties.id), [metadataService]),
        'Inventaris': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.inventaris.id), [metadataService]),
        'Effecten': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.effecten.id), [metadataService]),
        'Rechten & Vergunningen': useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.rechtenAndVergunningen.id), [metadataService]),
    };

And the handle save:

const handleSave = useCallback(async () =>
    {
        setLoading(true);

        Object.keys(data).forEach((x: string) => {
            mutationHandler.updateEntityWithProperty(
                dossier.entity,
                new FieldProperty(fields[x]),
                DataObjectValue.create(
                    new DataObject(
                        fields[x].specification,
                        {boolean: data[x]},
                    )
                ),
            );
        })

        try
        {
            await mutationHandler.commit();

            setLoading(false);
            enqueueSnackbar('Succesvol opgeslagen');
        }
        catch (e)
        {
            showError(e, 'Opslaan mislukt');

            setLoading(false);
        }
    }, [data, mutationHandler, dossier.entity, fields, enqueueSnackbar, showError]);

What did I miss, that whenever I want to wrap the fields in a useMemo:

const fields: { [p: string]: EntityField } = useMemo(() => ({

Eslint is screaming about useComputed?

Forgot to mention, this code is partly responsible for check boxes.

>Solution :

React hooks can’t be called from nested functions, i.e. the useCallback or useMemo callback functions.

Make all the useComputed calls on their own first, then memoize the fields object.

Example:

const Kredieten = useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.kredieten.id), [metadataService]);
const Deelnemingen = useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.deelnemingen.id), [metadataService]);
...
...
const RechtenVergunningen = useComputed(() => metadataService.getEntityField(RisicoAdviesDossier.PROPS.rechtenAndVergunningen.id), [metadataService]);

...

const fields: { [p: string]: EntityField } = useMemo(() => ({
  Kredieten,
  Deelnemingen,
  ...
  ...
  'Rechten & Vergunningen': RechtenVergunningen,
}), [Kredieten, Deelnemingen, ..., RechtenVergunningen]);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading