【发布时间】:2020-11-15 19:46:34
【问题描述】:
假设我有两个项目:A 和 B。这些项目有不同的选项。我想创建一个表单,允许我选择两个项目之一并设置该项目的选项。设置完选项后,我希望有一个处理程序来处理保存的选项。
我无法正确键入它,因为 A 和 B 的选项不相交,所以当我将选项传递到特定的项目表单组件时,它会给我一个 TypeScript 错误。
我将如何解决这个问题或更好的解决方法?
我在这里创建了一个示例应用程序:https://codesandbox.io/s/patient-bush-4emyo?file=/src/ItemCreator.tsx
错误“类型'选项'不可分配给类型'选项A和选项B'。”出现在这一行。
<Form options={options} setOptions={setOptions} />
这是主要的表单创建者:
import React, { useState, FC, useEffect } from "react";
import { OptionsAForm, OptionsA, defaultOptionsA } from "./OptionsAForm";
import { OptionsBForm, OptionsB, defaultOptionsB } from "./OptionsBForm";
type Options = OptionsA | OptionsB;
export const ItemCreator: FC = () => {
const [item, setItem] = useState<string>("A");
const [options, setOptions] = useState<Options>(defaultOptionsA);
useEffect(() => {
if (item === "A") {
setOptions(defaultOptionsA);
} else if (item === "B") {
setOptions(defaultOptionsB);
}
}, [item]);
let Form;
if (item === "A") {
Form = OptionsAForm;
} else if (item === "B") {
Form = OptionsBForm;
}
const handleSubmit = () => {
// do stuff with Options here
console.log(options);
};
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<select value={item} onChange={(e) => setItem(e.target.value)}>
<option value="" disabled>
Select an item
</option>
<option value="A">A</option>
<option value="B">B</option>
</select>
{Form && options != null && (
<Form options={options} setOptions={setOptions} />
)}
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
这些是选项的形式
import React, { FC } from "react";
export const defaultOptionsA: OptionsA = {
name: "",
color: ""
};
export interface OptionsA {
name: string;
color: string;
}
interface FormProps {
setOptions: (options: OptionsA) => void;
options: OptionsA;
}
export const OptionsAForm: FC<FormProps> = ({ options, setOptions }) => {
return (
<>
<input
placeholder="Name"
value={options.name}
onChange={(e) => setOptions({ ...options, name: e.target.value })}
/>
<input
placeholder="Color"
value={options.color}
onChange={(e) => setOptions({ ...options, color: e.target.value })}
/>
</>
);
};
import React, { FC } from "react";
export const defaultOptionsB: OptionsB = {
name: "",
weight: 0
};
export interface OptionsB {
name: string;
weight: number;
}
interface FormProps {
setOptions: (options: OptionsB) => void;
options: OptionsB;
}
export const OptionsBForm: FC<FormProps> = ({ options, setOptions }) => {
return (
<>
<input
placeholder="Name"
value={options.name}
onChange={(e) => setOptions({ ...options, name: e.target.value })}
/>
<input
type="number"
placeholder="weight"
value={options.weight}
onChange={(e) =>
setOptions({ ...options, weight: parseInt(e.target.value, 10) })
}
/>
</>
);
};
【问题讨论】:
-
将有趣的代码直接放入您的问题中。我们不应该链接到其他网站——这可能会腐烂——来获得有趣的部分。
-
我已经用相关的代码更新了我的帖子。
标签: reactjs typescript forms