javascript - NextJS 和 Formik:选择下拉菜单上的条件/动态呈现表单字段
问题描述
我的网页上Next.js
的条件渲染有问题。Formik
所以我在我的页面上命名了一个数组commands
,这很容易:
const commands = [
{
value: 'launch',
display_name: 'LAUNCH ROCKET!',
},
{
value: 'delay_launch',
display_name: 'LAUNCH IN..',
},
{
....list of elements, they are not API fetched!
}
];
我的页面上需要一个网络表单(组件)(基于Formik)
该组件如下所示:
<Container>
<Formik
initialValues={{ command: 'launch', arguments: 'test'}}
onSubmit={async (values, { setSubmitting }) => {
await setSubmitting(false);
await Router.push(`/${values.command}`);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
/* and other goodies */
}) => (
<form onSubmit={handleSubmit} noValidate autoComplete="off">
<Grid container spacing={3} direction="row" justify="center" alignItems="center">
<Grid item xs={3}>
<TextField
name="command"
select
label="Select command"
className={classes.dropdown}
onChange={handleChange}
onBlur={handleBlur}
value={values.command}
variant="outlined"
>
{commands.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Grid>
{/* IF COMMAND IN SELECT DROPDPWN === LAUNCH THEN RENDER THIS*/}
{values.command === "launch" && (
<React.Fragment>
<Grid item xs={3}>
<TextField
text-field
/>
</Grid>
<Grid item xs={1}>
<Typography variant="h3" align="center" style={{textTransform: 'uppercase', margin: '0'}}>
@
</Typography>
</Grid>
<Grid item xs={3}>
<TextField
another text-field
</TextField>
</Grid>
</React.Fragment>
)}
</Grid>
</form>
)}
</Formik>
</Container>
它(应该)如何工作?
当您在页面上选择下拉菜单时(以 Formik 的形式),它会呈现其他字段,具体取决于 select value。
问题:
如您所见,如果我继续这样编写代码,它会是一样的,就好像我if
一个接一个地编写每个语句一样。
因此,如果我的命令列表有 10 多个不同的命令,它将有 10 多个if
块。但我不需要以我的形式一次性渲染它们,使用commands.map =>
. 我只想查看表单中需要的那些字段,只有当在dropdown
.
像这样(伪代码风格):
IF IN MY FORM SELECTED COMMAND:
LAUNCH => THEN ADD 2 ADDITIONAL FIELDS IN THIS FORM
DELAYED LAUNCH => THEN ADD 3 ADDITIONAL FIELDS IN THIS FORM
...
那么如何实现呢?
我想我应该在我的数组中添加第三个字段commands
,例如:
const commands = [
{
value: 'launch',
display_name: 'LAUNCH ROCKET!',
render_code: `<React.Fragment>
<Grid item xs={3}>
<TextField
text-field
/>
</Grid>
<Grid item xs={1}>
<Typography variant="h3" align="center" style={{textTransform: 'uppercase', margin: '0'}}>
@
</Typography>
</Grid>
<Grid item xs={3}>
<TextField
another text-field
</TextField>
</Grid>
</React.Fragment>`
},
....
]
但是如何根据确定的选定值以我的形式呈现它?我想应该有类似的东西:Map.get(number)
,但我还没有找到任何例子,而且,我不知道渲染代码片段应该如何存储在数组中。如果我将它存储在一个string
值中,可以吗?
更新:
我正在尝试通过以下方式使用render_code
示例,例如上面的示例:
{commands.find(x => {if (x.value === values.command) return x.rendring_code})}
但问题是,如果将 JSX 片段存储为string
如下所示:
code: "<React.Fragment>\n <Grid item xs={3}>\n
有了所有这些\n
用于换行符和其他格式符号,但我不能存储纯JSX
,因为在这种情况下我有一个渲染错误,原因是只有在表单内部声明/定义<TextField>
的属性,而不是在页面外部。onChange={handleChange}
Formik
解决方案
我在 Formik 的 Github第 751 期和本文中发现了一个相关问题。所以我发现我的问题有点不同,但相关的解决方案。
这是一个片段@CodeSandbox和StackOverflow 的答案。
所以解决方案是基于原始表单的子组件,它是基于选择字段呈现的。(正是我需要的)。
不幸的是,我没有解决重复代码的问题,而是很好地构建代码并只呈现表单的必要部分。
推荐阅读
- c - 如何在 gdb 中“展开”核心转储
- amazon-web-services - 如何停止接收“AWS 通知消息”
- reactjs - 我正在使用带有 reactjs 的 https://flickity.metafizzy.co/ 轮播,但反应路由器破坏了轮播。请阅读描述和照片
- python - 为什么 Airflow 继续运行 DAG?
- data-visualization - TABLEAU 总计与视图中的不匹配
- na - Excel 上的空单元格不处理为 NA
- android - Android:在 ViewFlipper 内的按钮上执行单击()?
- python - 字符串连接布尔值两次返回 True
- python - mysql循环查询平均python
- rust - 弧
> 内部闭包:期望一个实现了 `Fn` 特性的闭包,但这个闭包只实现了 `FnOnce`