【发布时间】:2022-07-28 02:59:18
【问题描述】:
我正在使用 ReactJS 和 MUI 组件来创建基于以下 JSON 的动态表单。
{
"form": {
"groups": [{
"group_id": "acfcbaa6-3bb9-45c0-ad0a-cb5237359bbb",
"group_name": "Group 1",
"elements": [{
"element_id": "dfc81836-3bb9-45c0-ad0a-cb5237359ba9",
"element_name": "report_type_id",
"element_type": "S",
"label": "Select a product",
"required": false,
"display": true,
"options": [{
"option_id": "0479f2a1-fd8f-487e-8d46-1f3a5572a6a1",
"option_name": "Product 1",
"elements": []
},
{
"option_id": "0479f5f1-fd8f-487e-8d46-1f3a5572a6a8",
"option_name": "Product 2",
"elements": []
},
{
"option_id": "0479sda1-fd8f-487e-8d46-1f3a5572a6a0",
"option_name": "Product 3",
"elements": []
},
{
"option_id": "0479f2a1-fd8f-487e-8d46-1f3a5572a6bb",
"option_name": "Product 4",
"elements": []
}
]
},
{
"element_id": "05bea614-6dc6-4c89-99db-fa6fa791728b",
"element_name": "product_price",
"element_type": "T",
"label": "Product Price",
"required": false,
"display": true,
"options": []
},
{
"element_id": "05bea614-6dc6-4c89-99db-fa6fa791728b",
"element_name": "product_category",
"element_type": "S",
"label": "Product Category",
"required": false,
"display": true,
"options": [{
"option_id": "b479f2a1-fd8f-487e-8d46-1cca5572a6a1",
"option_name": "Product Cat 1",
"elements": []
},
{
"option_id": "b479f5f1-fd8f-487e-6f46-1f3a5572a6a8",
"option_name": "Product Cat 2",
"elements": []
},
{
"option_id": "0549sda1-fd8f-487e-4d46-1f3a5572a6a0",
"option_name": "Product Cat 3",
"elements": []
},
{
"option_id": "a479fcb1-fd8f-487e-8d46-1f3a5572a6bb",
"option_name": "Product Cat 4",
"elements": []
}
]
},
{
"element_id": "05bea614-6dc6-4c89-99db-fa6fa791728b",
"element_name": "payment_method",
"element_type": "S",
"label": "Payment Method",
"required": false,
"display": true,
"options": [{
"option_id": "b479f2a1-fd8f-487e-8d46-1cca5572a6a1",
"option_name": "Cash",
"elements": []
},
{
"option_id": "0549sda1-fd8f-487e-4d46-1f3a5572a6a0",
"option_name": "Credit Card",
"elements": [{
"element_id": "4745aca7-beb6-4892-9f68-05b1609e56d9",
"element_name": "credit_card",
"element_type": "CC",
"label": "Credit Card"
},
{
"element_id": "42159553-f2c3-4bab-978c-6ac76e65989b",
"element_name": "cc_exp_month",
"element_type": "T",
"label": "Expiration Month"
},
{
"element_id": "9b693880-210b-4946-bf9c-da99a44b3fb6",
"element_name": "cc_exp_year",
"element_type": "T",
"label": "Expiration Year"
},
{
"element_id": "14c7b16d-5595-42fb-ba75-6517ffbd0cdc",
"element_name": "cc_code",
"element_type": "T",
"label": "Code"
},
{
"element_id": "56f6ebf7-4dc0-4609-a2fc-dc7d19859e69",
"element_name": "billing_first_name",
"element_type": "T",
"label": "Billing First Name"
},
{
"element_id": "1f084d95-be3d-4bba-814b-83a51f27e0df",
"element_name": "billing_last_name",
"element_type": "T",
"label": "Billing Last Name"
}
]
}
]
}
]
}]
}}
如您所见,这个 json 具有嵌套结构,并且嵌套的深度没有限制。所以我们有一个复杂的嵌套形式。问题是——我们如何维护一个表单文档,当表单元素的值发生变化时它会更新。我使用 useState 钩子并在顶层维护一个状态对象,并使用回调将嵌套值传递回父表单(a形成了深度回调链,但完成了工作)。但是,每次更改单个值时,都会渲染整个表单,这不是很理想。任何人都可以提出更好的解决方案吗?专业的 React 开发人员将如何处理这样的用例?
【问题讨论】:
-
我假设你有一个受控的输入组件,并且表单有很多输入组件,而你只有一个状态对象来承载整个表单的状态,防止不必要计算的理想方法是用 React.memo 包装你的输入组件。
-
“每次单个值更改时,都会呈现整个表单” - 这就是 React 的工作方式。当父组件渲染时,它会渲染其 整个 子 ReactTree。使用
React.mempHOC 将子 ReactTree 中的组件包装起来,以帮助指示/提示 React 可能不需要组件重新渲染 到 DOM,因为传递了 prop 值没有改变。您只分享了您的数据,但如果您分享如何呈现表单和字段,我们可能会提出更好的建议。
标签: reactjs