1

I am creating a formulary from json response, so I create element in another function with the input I recieves, the json has this format:

const clientInfo = {
        "policyHolder" : {
            "carrierName":"Medi NY",
            "memberId":"D02Z",
            "subscriberId":"289",
            "zipCode":"12119",
            "firstName":"Jim",
            "lastName":"larren",
            "dob":"01/25/1949",
            "address":"North Road",
            "phone":"(241)221-5996",
            "email":"jimlarr@email.com" 
        },
        "patient" : [
        {
            "patientId":"2090",
            "lastName":"Larren",
            "firstName":"Sergio",
            "dob":"02/14/1996",
            "relationship":"other"
        },
    ],
        "responsibleParty" : {
            "guarantorId":"5009",
            "lastName":"Sara",
            "firstName":"Larren",
            "dob":"10/15/1966",
            "address":"North Road",
            "phone":"(241)221-5996",
            "email":"jimlarr@email.com"
        }

I retrieved it from an API set it into a useState var, then pass it in props to the component, and in the component file I set the props in two states var.

// main
useEffect( async () => {
        setclientInfo(await fetchPatientInfo(id))
    }, []);

<FormInput client={clientInfo} />

// FormInput

const [policymember, setpolicymember] = useState(client);
const [helperPolicy, sethelperPolicy] = useState(client);

I do this because I want policymember, to be the preset data in my text fields, and policyholder to be the helper text of my text fields, so I need them to have the same structure but different values, but when I modifie policymember the data inside helper policy changes too, how can I avoid this?

here is how I change the states:

function formatInput(){
        setpolicymember((prevState) => {
            let tempmember = Object.assign({}, prevState);
            for(let fkey of Object.keys(tempmember)){
                if(tempmember[fkey] instanceof Object){
                    if(tempmember[fkey].constructor == Object){
                        for(let skey of Object.keys(tempmember[fkey])){
                            if(tempmember[fkey][skey].toLowerCase() == "empty"){
                                tempmember[fkey][skey] = "";
                                console.log("**** policy ****", tempmember[fkey][skey])
                            }
                        }
                    }else if(tempmember[fkey].constructor == Array){
                        tempmember[fkey].forEach((el, pos) => {
                            for(let skey of Object.keys(tempmember[fkey][pos])){
                                if(tempmember[fkey][pos][skey].toLowerCase() == "empty"){
                                    tempmember[fkey][pos][skey] = "";
                                }
                            }
                        });
                    }
                }
            }
            return tempmember
        });
    }

    function setHelperText(){
        sethelperPolicy((prevState) => {
            let tempmember = Object.assign({}, prevState);
            for(let fkey of Object.keys(tempmember)){
                if(tempmember[fkey] instanceof Object){
                    if(tempmember[fkey].constructor == Object){
                        for(let skey of Object.keys(tempmember[fkey])){
                            if(tempmember[fkey][skey].toLowerCase() == "empty"){
                                tempmember[fkey][skey] = "*Required";
                                console.log("**** Helper ****", tempmember[fkey][skey])
                            }
                        }
                    }else if(tempmember[fkey].constructor == Array){
                        tempmember[fkey].forEach((el, pos) => {
                            for(let skey of Object.keys(tempmember[fkey][pos])){
                                if(tempmember[fkey][pos][skey].toLowerCase() == "empty"){
                                    tempmember[fkey][pos][skey] = "*Required";
                                }
                            }
                        });
                    }
                }
            }
            return tempmember
        })
    }

useEffect(()=>{
        formatInput();
        setHelperText();
        console.log("mounting");
    },[])
Landy Cuadra
  • 165
  • 11
  • You will need to clone them each if you don't want them passed as references, and since the client objects contain nested objects you will need deep clone. see: [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) – pilchard Feb 16 '21 at 02:56
  • Hi @pilchard, I have already tried with Object.asign(), but the simultaneous changing still, happening – Landy Cuadra Feb 16 '21 at 03:04

1 Answers1

1

When you do this:

const [policymember, setpolicymember] = useState(client);
const [helperPolicy, sethelperPolicy] = useState(client);

basically, you copy the address or alias of the same variable, so replace it with:

const [policymember, setpolicymember] = useState(() => JSON.parse(JSON.stringify(client)));
const [helperPolicy, sethelperPolicy] = useState(() => JSON.parse(JSON.stringify(client)));

this JSON.parse(JSON.stringify(client)) create a copy of the same variable without alias is not so fast, but works

...edited answer...

FrankSiret
  • 186
  • 8
  • Hi Frank, I have Already tried this, but still happening – Landy Cuadra Feb 16 '21 at 03:14
  • try this, deep cloning object, obj = JSON.parse(JSON.stringify(client)) – FrankSiret Feb 16 '21 at 03:24
  • it Work!, thank you so much, but my question is why this option worked and all the others don't? – Landy Cuadra Feb 16 '21 at 03:36
  • 1
    When you use the assignment operator, it copies the memory address of the object and not the data itself, another example is let a = [1]; let b = a; b [0] = 0; now a = [0], because when you changed the value of 'b', this change that of 'a' which is its address. Happen with non-primitive variables. On the other hand, the json parser, converts the variable to string and builds it from scratch, as different data – FrankSiret Feb 16 '21 at 03:52