Reputation: 2563
I'm not new to ReactJs but somehow when I console.log in my component function it shows that already set properties are also reset. below is my complete functional component
import React, { useState } from 'react';
import {
Grid, Typography, Paper, TextField,
} from '@material-ui/core';
import Autocomplete from '@material-ui/lab/Autocomplete';
import SomeComponent from '../../common/SomeComponent';
import countries from '../../utils/countries_data';
import AlertMsg from '../../utils/Alert';
import { MarkRequired } from '../style';
const App = ({ classes, handleNext, handlePay }) => {
const [contact, setContact] = useState({
firstName: '',
lastName: '',
address1: '',
});
const handleChange = (e) => setContact({
...contact,
[e.target.name]: e.target.value,
});
console.log('above splitAddressProperties', contact);
const splitAddressProperties = (data) => {
console.log('func start', contact);
const country = countries.filter(
(count) => count.alpha2 === data.country_code || count.alpha3 === data.country_code,
);
setContact({
...contact,
address1: data.address,
city: data.city,
zip: data.zip,
country: country[0],
});
console.log('func end', contact);
};
return (
<Grid item xs={12}>
<Paper className={classes.paper}>
<Typography className={classes.inputText}>Contact Information</Typography>
<Grid container style={{ marginBottom: '15px' }}>
<Grid item xs={6} style={{ paddingRight: '10px' }}>
<Typography className={classes.inputTitle}>
First Name
<MarkRequired>*</MarkRequired>
</Typography>
<input
className={classes.inputsty}
value={contact.firstName}
onChange={handleChange}
type="text"
name="firstName"
/>
</Grid>
<Grid item xs={6} style={{ paddingLeft: '10px' }}>
<Typography className={classes.inputTitle}>
Last Name
<MarkRequired>*</MarkRequired>
</Typography>
<input
className={classes.inputsty}
value={contact.lastName}
type="text"
onChange={handleChange}
name="lastName"
/>
</Grid>
</Grid>
<Grid style={{ marginBottom: '15px' }}>
<Typography className={classes.inputTitle}>
Address
<MarkRequired>*</MarkRequired>
</Typography>
<SomeComponent
className={classes.inputsty}
value={contact.address1}
onChange={splitAddressProperties}
/>
</Grid>
</Paper>
</Grid>
);
};
export default App;
if I enter the first and last name and enter SomeComponent value splitAddressProperties
is triggered but it shows that contact's value is as same as default. thing to note is that console.log('above splitAddressProperties', contact); fires two times when first andd last names are entered.
Upvotes: 1
Views: 1063
Reputation: 1102
I'ts not enough information to really find the problem, but I'm guessing that SomeComponent stores and uses an old reference of the onChange prop.
For example:
const SomeComponent = (props) => {
// ...
const innerOnChange = useCallback(
(data) => {
props.onChange(data);
},
// Note that the deps array doesn't have onChange:
[]
);
// ...
}
What I would do is access the current contact from the setState:
setContact(currentContact => ({
...currentContact,
address1: data.address,
city: data.city,
zip: data.zip,
country: country[0],
}));
setContact
's reference will never change and it will always give you the current contact object. (But it's better to fix SomeComponent
)
Upvotes: 3