Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Unable To Overwrite Auto Populating Custom Text Field

default discord avatar
aayush214last year

I have a custom field which is a calculated value that depends on 2 sibling fields. The following function uses setValue to populate that field inside of a useEffect function with siblings as dependencies.



The problem:

If I manually change that field (which at times I would like to), it persists to the database with the overwritten value, but upon page refresh it shows the calculated field since the useEffect runs on load. Is there a way in payload to make it effect only if a sibling value is changed manually and not on load? is useEffect the correct way to do it?



import React, { useEffect } from "react"; import { useField, useAllFormFields, reduceFieldsToValues, Label, TextInput, } from "payload/components/forms"; import { Props } from "payload/components/fields/Text"; export const CustomOutgoingPayment: React.FC<Props> = ({ path, label, name, }) => { const { value, setValue } = useField<string>({ path }); const [fields] = useAllFormFields(); const formData = reduceFieldsToValues(fields, true); const calculationFunction = () => { let calculatedOutgoingPayment = formData?.incomingPayment - formData?.incomingPayment * (formData?.calculationPercentage / 100); setValue(calculatedOutgoingPayment); }; useEffect(() => { calculationFunction(); }, [formData.incomingPayment, formData.calculationPercentage]); return ( <> <Label label={label} /> <TextInput value={value !== undefined ? value : ""} name={name} path="OutgoingPaymentField" onChange={(e) => setValue(e.target.value)} /> </> ); };


I suppose it became more of a React question. I managed to solve this by changing the useEffect() to use the mount pattern with a custom hook. Code is as follows:



Replace the useEffect with the following:



const useEffectAfterMount = (cb, dependencies) => { const mounted = useRef(true); useEffect(() => { if (!mounted.current) { return cb(); } mounted.current = false; }, dependencies); }; useEffectAfterMount(() => { calculationFunction(); }, [formData.incomingPayment, formData.calculationPercentage]);
    Star on GitHub

    Star

    Chat on Discord

    Discord

    online

    Can't find what you're looking for?

    Get dedicated engineering support directly from the Payload team..