设置通过 props 接收的表单元素初始值
Set form element initial value which is received via props
我正在使用 React Hooks 来处理一个简单的表单。我收到 'transaction' 对象作为道具,我想根据这个对象设置输入值,因为我正在尝试更新这个 'transaction'
正如您在下面看到的,我正在尝试根据 'transaction' 对象设置我的描述输入值,我收到的是 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>
)
}
这个 'transaction' 对象最初看起来像这样:
{
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 and store "oldProps" with useRef:
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]);
...
我正在使用 React Hooks 来处理一个简单的表单。我收到 'transaction' 对象作为道具,我想根据这个对象设置输入值,因为我正在尝试更新这个 'transaction'
正如您在下面看到的,我正在尝试根据 'transaction' 对象设置我的描述输入值,我收到的是 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>
)
}
这个 'transaction' 对象最初看起来像这样:
{
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 and store "oldProps" with useRef:
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]);
...