【发布时间】:2021-10-06 10:25:27
【问题描述】:
我在 typescript web 应用程序中使用 formik 2.2.9,但我遇到了 html 选择元素的问题。
所以,我的表单有这样的控件:
export interface CriterionEdit {
id: number;
name: string;
description: string;
isDeleted: boolean;
interval: number;
groupId: number;
}
我写了这样的代码:
public render() {
return (
<React.Fragment>
<h1>Edit</h1>
<Formik
enableReinitialize
initialValues={this.props.criterion}
onSubmit={(values) => {
// https://github.com/formium/formik/issues/1191#issuecomment-607333552 waiting v 3.0.0
values.interval = parseInt(values.interval as any, 10);
values.groupId = parseInt(values.groupId as any, 10);
values.isDeleted = (values.isDeleted as any) === "true";
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(values),
};
fetch("/criterion/update/", requestOptions).then(
() => (window.location.href = "/criteria/my")
);
}}
>
<Form translate="yes">
<Field name="id" type="hidden" />
<div className="form-group">
<label htmlFor="name">Criterion title</label>
<Field name="name" className="form-control" type="text" />
</div>
<div className="form-group">
<label htmlFor="interval">Interval</label>
<Field
name="interval"
as="select"
type="text"
className="form-control"
value={this.props.criterion.interval.toString()}
title="interval"
>
<option value="0">week</option>
<option value="1">month</option>
<option value="2">quarter</option>
<option value="3">half-year</option>
<option value="4">year</option>
</Field>
</div>
<div className="form-group">
<label htmlFor="isDeleted">IsDeleted</label>
<Field
name="isDeleted"
as="select"
className="form-control"
value={this.props.criterion.isDeleted.toString()}
title="isDeleted"
>
<option value="false">no</option>
<option value="true">yes</option>
</Field>
</div>
<div className="form-group">
<label htmlFor="groupId">Group</label>
<Field
name="groupId"
as="select"
type="number"
className="form-control"
value={this.props.criterion.groupId.toString()}
title="group"
>
{this.props.groups.map((option) => (
<option key={option.id} value={option.id}>
{option.title}
</option>
))}
</Field>
</div>
<div className="form-group">
<label htmlFor="description">Description</label>
<Field
name="description"
as="textarea"
className="form-control"
/>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</Form>
</Formik>
</React.Fragment>
);
}
因此,问题的关键在于我的选择值不是字符串,而是 html 规范将所有选择框视为具有文本值的元素。而且 fomik 有自己的restrictions。
好的,我可以在选择后解析确切的类型(使用丑陋的'as any'),但我无法显示初始值:
当我指定 value={this.props.criterion.something.toString()} 时,我有一个渲染错误。我可以从 select 中更改另一个值,它会更改内部 formik 值(并正确发送到服务器端),但不会重新呈现视觉状态。
我可以删除value={this.props.criterion.something.toString()},所以我的初始值(我从api调用中检索它们,这就是我使用enableReinitialize的原因)无法正确显示。
官方文档包含带有文本选择框的示例,没有整数/布尔值。所以我无法理解处理类似问题的推荐方法,也许有人已经遇到过这个问题?也许,我走错了路,我需要更改我的代码(例如使用'onChange')?我尝试了不同类型的选择框(type="number" 和 type="text"),但这并不影响。
【问题讨论】:
标签: reactjs typescript formik