reactjs - 设置通过 props 接收的表单元素初始值
问题描述
我正在使用 React Hooks 来处理一个简单的表单。我收到“交易”对象作为道具,我想根据这个对象设置输入值,因为我正在尝试更新这个“交易”
正如您在下面看到的,我正在尝试根据“交易”对象设置我的描述输入值,我将其作为道具接收
//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并将“oldProps”与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]);
...
推荐阅读
- javascript - 如何在节点js的不同文件中编写单元测试
- python - 如何在测试期间将参数传递给请求?
- python - 部署后通过 terraform 调用 lambda 时出错。在 Cloudwatch 中找不到任何日志
- android - 在 Qt for Android 中使用 .aar
- javascript - 如何在 NodeJS API 的基本路由器上附加新字符串?
- r - 如何循环数组并将操作值存储在其他数组中
- arrays - 有没有办法将 'char (*)[10]' 更改为 'char *'?
- python - PySide6 慢速 UTF-8 显示
- verilog - 当下一个状态组合逻辑块转换中的“当前状态”值时,系统 Verilog FSM“下一个状态”不会转换 - 三元运算符
- python - 我究竟如何修改 VSCode 扩展“vscode-code-runner”的配置?