This is the set up:
In App.js i have routes for each step. i have a main object in which im updating values as the steps progress using props.
Here is my object:
const [postData, setPostData2] = useState({
'meta': {
"originally_created": todaysDate,
"user_agent": navigator.userAgent,
"ip_address": ip,
"tcpa_compliant": true,
"tcpa_consent_text": "By clicking Get My Free Quote below, I am agreeing to receive text messages from InsurTech Groups and business partners. I provide my signature expressly consenting to recurring contact from InsurTech Groups or its business partners at the number I provided regarding products or services via live, automated or prerecorded telephone call, text message, or email. I understand that my telephone company may impose charges on me for these contacts, and I am not required to enter into this agreement as a condition of purchasing property, goods, or services. I understand that I can revoke this consent at any time. Terms & conditions & Privacy policy apply.",
"landing_page_url": ""
},
"contact": {
"first_name": "",
"last_name": "",
"email": "",
"phone": "",
"address": "",
"city": "",
"state": "",
"zip_code": "",
"ip_address": ip,
},
"data": {
"drivers": [
{
"first_name": "",
"last_name": "",
"birth_date": "",
"gender": "",
},
{
"first_name": "",
"last_name": "",
"birth_date": "",
"gender": "",
}
],
"vehicles": [{
"year": "",
"make": "",
"model": "",
},
{
"year": "",
"make": "",
"model": "",
}
],
"requested_policy": {
"coverage_type": "",
},
"current_policy": {
"insurance_company": "",
}
}
});
Here is some logic so i can update the object with props:
useEffect(() => {
const stringifiedData = sessionStorage.getItem('main-form-data')
if (stringifiedData) {
const jsonData = JSON.parse(stringifiedData);
setPostData(jsonData);
}
}, []);
useEffect(() => {
sessionStorage.setItem('main-form-data', JSON.stringify(postData));
}, [JSON.stringify(postData)]);
const setPostData = (obj) => {
console.log('in app state', obj);
setPostData2(obj)
}
const setPostDataForPage = (data) => {
setPostData({ ...postData, ...data });
}
and this is how im passing it into each route:
<Route
path="/car-year"
element={<CarYear setPostData={setPostDataForPage} />}
/>
<Route
path="/car-make"
element={<CarMake setPostData={setPostDataForPage} />}
/>
<Route
path="/car-model"
element={<CarModel setPostData={setPostDataForPage} />}
/>
So here is the issue:
As i updated Car Year, Car Make & Car Model it updates in the console log as it supposed to but everytime it console log it completely overwrites the prior object.
Example:
YEAR STEP:
....rest of console log from object
vehicels: year: 1991
MAKE STEP:
....rest of console log from object
vehicels: make: Honda
as you can see it just over writes the year and replaces it with just the make
Here is how im updating in each step:
CAR YEAR PROPS UPDATE:
props.setPostData({
vehicles:
{
year: year,
}
})
CAR MAKE PROPS UPDATE:
props.setPostData({
vehicles: [
{
make: make,
}
]
})
Why does it do this and how can i fix it?
Here is a *bonus question lol, if i have two vehicles how can i make sure that when the person enters a second vehicle it doenst overwrite the first vehicle data!
I know this one is super long and thank you in advance!!!! <3
CodePudding user response:
You're spreading the original state in the setter. React won't mutate the state synchronously, so you end calling all 3 setters on the original state.
To use the actual state, pass a callback to the state setter with the previous state as the parameter.
const setPostDataForPage = (data) => {
setPostData(prevData => { ...prevData, ...data });
}