skip to Main Content

My React application doesn’t use Formik or other libraries, but simply defines a Map of field values. That Map of Values, along with the setter function, is passed to different components. E.g.

Top-Level Component

const [valueMap, setValueMap] = useState(new Map());

const initializeValueMap = () => {
   var valMap = new Map();
   valMap.set('field1', '');
   //...
   valMap.set('street', '');
   valMap.set('city', '');
   valMap.set('state', '');
   valMap.set('zip', '');
   valMap.set('streetMailing', '');
   valMap.set('cityMailing', '');
   valMap.set('stateMailing', '');
   valMap.set('zipMailing', '');
   setValueMap(valMap);

Address Component

<Address handleValueMapChange={handleValueMapChange} valueMap={valueMap} />

There are 2 radio buttons: (1) Mailing Address Same As Main, (2) Mailing Address Different From Main. If the mailing address is different, the XXXMailing variables will be individually set. If the 1st radiobutton is clicked, the Address fields will be copied over into XXXMailing from XXX.

Now if the Same radio button is already selected and then the user changes the Main Address fields, I need to listen for that and automatically propagate to the XXXMailing fields as well.

But I can’t have an Effect like

useEffect(() => {
    if (props.valueMap.get('sameAsMA') === true) {
        // ... Propagate to Mailing equivalents ...
    }
}, [props.valueMap.street, props.valueMap.city, props.valueMap.state, props.valueMap.zip]);

because those aren’t available variables, those are values in a Map. The only thing I can do is

useEffect(() => {
    if (props.valueMap.get('sameAsMA') === true) {
        // ... Propagate to Mailing equivalents ...
    }
}, [props.valueMap]); // The whole Map change

which would create an infinite loop, because I’d be continuously changing the Map. Any suggestions?

2

Answers


  1. Chosen as BEST ANSWER

    I fixed my issue. To avoid an infinite loop, I can restrict the Effect by which map values are different. The Effect will stop applying when they're the same and have been copied over.

    useEffect(() => {
        if (props.valueMap.get('sameAsMA') === true && 
            (
                props.valueMap.get('street') !== props.valueMap.get('streetMailing') || 
                props.valueMap.get('city') !== props.valueMap.get('cityMailing') || 
                //...
            )
        ) {
            props.handleValueMapChange("streetMailing", props.valueMap.get('street'));
            props.handleValueMapChange("cityMailing", props.valueMap.get('city'));
            //...
          }
    }, [props.valueMap]);
    

  2. you should change your logic and rethink a little:

    1. make buttons like "use different shipping address"
    2. add a state var to check if the mode is active or if your using billing one
    3. with onchanged on the button the object will be filled
    4. use onfocusout on the billing address, check in the function you call if the different billing is active, if? Then do the copy.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search