我正在使用 React Hooks 来处理一个简单的表单。我收到"交易"对象作为道具,我想基于此对象设置输入值,因为我正在尝试更新此"交易">
正如您在下面看到的,我正在尝试根据"交易"对象设置我的描述输入值,我将其作为 prop 接收
//TransactionsForm.js
const TransactionsForm = ({ onSubmit, transaction }) => {
const [values, setValues] = useState({
description: transaction.description
})
const handleChange = event => {
const { name, value } = event.target
setValues({ ...values, [name]: value })
}
return (
<form>
<input
type="text"
placeholder="description"
name="description"
value={values.description}
onChange={handleChange}
/>
<button>Submit</button>
</form>
)
}
这个"事务"对象最初看起来像这样:
{
id: null,
description: '',
transactionType: '',
date: '',
category: '',
amount: ''
}
但是当用户单击编辑按钮并将其设置为单击的交易对象以传递给我的 TransactionsForm 时,我会更新它.js从而基于此更新表单输入值。
如果我像这样设置我的输入值
<input
type="text"
placeholder="description"
name="description"
value={transaction.description} // like this it's working, but when I use values.description the value is not updating
onChange={handleChange}
/>
我想当道具更改时TransactionsForm
更新值时会遇到问题。 useState
仅在第一次渲染时设置初始值,并且在道具更改时不会更新它。您需要手动执行此操作:
const TransactionsForm = ({ onSubmit, transaction }) => {
const [values, setValues] = useState({
description: transaction.description
});
useEffect(() => setValues(
oldValues => (
{...oldValues, description: transaction.description}
)
), [transaction.description]);
...
useEffect
将在初始渲染时调用,并且每次transaction.description
都会获得一个新值。由于setValues
收到一个新对象,因此在初始对象之后,您将获得不必要的额外渲染。为避免这种情况,您可以仅将description
存储在您的状态中:
const [descripton, setDescription] = useState(transaction.description);
如果你真的需要一个复杂的状态结构,请考虑使用useReducer并使用useRef存储"oldProps":
const TransactionsForm = ({ onSubmit, transaction }) => {
const [values, setValues] = useState({
description: transaction.description
});
const oldDescription = useRef(transaction.description);
useEffect(() => {
if (oldDescription.current !== transaction.description) {
oldDescription.current = transaction.description;
setValues(
oldValues => (
{...oldValues, description: transaction.description}
)
);
}
}, [transaction.description]);
...