onChange 正在重置状态 - useState
onChange is resetting state - useState
我不是 ReactJs 的新手,但是当我在我的组件函数中 console.log 时,它显示已经设置的属性也被重置。下面是我完整的功能组件
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;
如果我输入名字和姓氏并输入 SomeComponent 值 splitAddressProperties
将被触发,但它显示联系人的值与默认值相同。需要注意的是 console.log('above splitAddressProperties', contact);输入名字和姓氏时触发两次。
我没有足够的信息来真正找到问题,但我猜测 SomeComponent 存储并使用了 onChange 道具的旧引用。
例如:
const SomeComponent = (props) => {
// ...
const innerOnChange = useCallback(
(data) => {
props.onChange(data);
},
// Note that the deps array doesn't have onChange:
[]
);
// ...
}
我要做的是从 setState 访问当前联系人:
setContact(currentContact => ({
...currentContact,
address1: data.address,
city: data.city,
zip: data.zip,
country: country[0],
}));
setContact
的引用永远不会改变,它总是给你当前的联系人对象。 (不过还是修复一下比较好SomeComponent
)
我不是 ReactJs 的新手,但是当我在我的组件函数中 console.log 时,它显示已经设置的属性也被重置。下面是我完整的功能组件
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;
如果我输入名字和姓氏并输入 SomeComponent 值 splitAddressProperties
将被触发,但它显示联系人的值与默认值相同。需要注意的是 console.log('above splitAddressProperties', contact);输入名字和姓氏时触发两次。
我没有足够的信息来真正找到问题,但我猜测 SomeComponent 存储并使用了 onChange 道具的旧引用。
例如:
const SomeComponent = (props) => {
// ...
const innerOnChange = useCallback(
(data) => {
props.onChange(data);
},
// Note that the deps array doesn't have onChange:
[]
);
// ...
}
我要做的是从 setState 访问当前联系人:
setContact(currentContact => ({
...currentContact,
address1: data.address,
city: data.city,
zip: data.zip,
country: country[0],
}));
setContact
的引用永远不会改变,它总是给你当前的联系人对象。 (不过还是修复一下比较好SomeComponent
)