如何根据另一个 selection 在各种索引值处设置 Formik FieldArray select 选项
How to set Formik FieldArray select options at various index values based on another selection
我正在使用由以下字段组成的 Formik FieldArray:
Pet Type
Pet Food
我对这个 FieldArray 的 initialValues
设置如下:
const myPetGroup = {
petDetails: [
{
petSelection: [
{
petType: "",
petFood: ""
}
]
}
]
};
const INITIAL_FORM_STATE = {
allPets: [myPetGroup]
}
基于 Pet Type
的 selection 值,我需要将一组特定的选项分配给 Pet Food
。显然,我需要确保在每个行索引级别维护值。
假设我有以下选项 Pet Type
const petListOptions = [
{ value: "dog", label: "Dog" },
{ value: "cat", label: "Cat" }
];
以下是基于宠物的两种食物选择selection:
const dogFood = [
{ value: "dog food choice a", label: "Dog Food A" },
{ value: "dog food choice b", label: "Dog Food B" }
];
const catFood = [
{ value: "cat food a", label: "Cat Food A" },
{ value: "cat food b", label: "Cat Food B" }
];
假设我的 FieldArray 索引为 0:
<Select
name={`petType.${index}`}
options={petListOptions}
value={dog}
/>
基于 Pet Type
selection of dog
然后我如何设置以下 select
以在索引 0 处具有 dogFood
的选项,即:
<Select
name={`petFood.${index}`}
options={dogFood}
/>
现在如果用户在 FieldArray 中添加另一行,现在在索引 1 和现在 select cat
,我如何设置选项现在在索引 1 使用 catFood
?
<Select
name={`petType.${index}`}
options={petListOptions}
value={cat}
/>
<Select
name={`petFood.${index}`}
options={catFood}
/>
我不确定如何根据我的 FieldArray 中的宠物列表 selection 在各种索引处设置这些宠物食品选项。
因此,为了正确理解,您必须呈现一个控件列表,一个选择哪种类型的宠物,然后根据第一个选择,程序呈现可供选择的食物选项。
const petListOptions = [
{ value: "dog", label: "Dog" },
{ value: "cat", label: "Cat" }
];
从第一个列表中选择的值将决定接下来要呈现的选项。因此,为了便于检索,我保留了下面的 petFood 数组的键,以匹配从上面的第一个选择返回的一组可能值。
const petFood = {
dog: [
{ value: "dog food choice a", label: "Dog Food A" },
{ value: "dog food choice b", label: "Dog Food B" }
],
cat: [
{ value: "cat food a", label: "Cat Food A" },
{ value: "cat food b", label: "Cat Food B" }
]
};
为了保存 petType 和 petFood 的值,我们传递了一个数组,其中第一个对象已初始化,其中 petType 和 food 属性都设置为空。
这将只呈现一组行。
在下面的代码中:<Field name={
petSelection.${index}.petType} as="select" value={selectedPet.petType}> ... </Field>
告诉 formik 如何存储选择的值。
注意 FieldArray 上的 name
属性。您要存储值的 属性 应该是 FieldArray's name <dot> Index
。如果我们想将我们的值放在特定的 属性 中,我们可以将 <dot> Property name
附加到我们的 Select 字段的名称。
export const PetsList = () => (
<div>
<h1>Pet List</h1>
<Formik
initialValues={{
petSelection: [
{
petType: "",
petFood: ""
}
]
}}
onSubmit={(values) =>
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
}, 500)
}
render={({ values }) => (
<Form>
<FieldArray
name="petSelection"
render={(arrayHelpers) => (
<div>
{values.petSelection && values.petSelection.length > 0 ? (
values.petSelection.map((selectedPet, index) => {
//console.log("selectedPet" + index, selectedPet);
return (
<div key={index}>
<Field
name={`petSelection.${index}.petType`}
as="select"
value={selectedPet.petType}
>
<option value="" disabled />
{petListOptions.map((pet, petIndex) => (
<option value={pet.value}>{pet.label}</option>
))}
</Field>
{selectedPet.petType && (
<Field
name={`petSelection.${index}.petFood`}
as="select"
value={selectedPet.petFood}
>
<option value="" disabled />
{petFood[selectedPet.petType].map(
(food, foodIndex) => (
<option value={food.value}>{food.label}</option>
)
)}
</Field>
)}
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a friend from the list
>
-
</button>
<button
type="button"
onClick={() =>
arrayHelpers.insert(index, {
petType: "",
petFood: ""
})
} // insert an new object at a position
>
+
</button>
</div>
);
})
) : (
<button
type="button"
onClick={() => arrayHelpers.push({
petType: "",
petFood: ""
})}>
{/* show this when user has removed all pets from the list */}
Add a Pet
</button>
)}
<div>
<button type="submit">Submit</button>
</div>
</div>
)}
/>
</Form>
)}
/>
</div>
);
添加按钮只是将一个新对象添加到 petsSelection
数组,属性 petType
和 petFood
初始化为空字符串。
现在,在您进行选择的任何行中,您一定要将值添加到这个新对象!
我正在使用由以下字段组成的 Formik FieldArray:
Pet Type
Pet Food
我对这个 FieldArray 的 initialValues
设置如下:
const myPetGroup = {
petDetails: [
{
petSelection: [
{
petType: "",
petFood: ""
}
]
}
]
};
const INITIAL_FORM_STATE = {
allPets: [myPetGroup]
}
基于 Pet Type
的 selection 值,我需要将一组特定的选项分配给 Pet Food
。显然,我需要确保在每个行索引级别维护值。
假设我有以下选项 Pet Type
const petListOptions = [
{ value: "dog", label: "Dog" },
{ value: "cat", label: "Cat" }
];
以下是基于宠物的两种食物选择selection:
const dogFood = [
{ value: "dog food choice a", label: "Dog Food A" },
{ value: "dog food choice b", label: "Dog Food B" }
];
const catFood = [
{ value: "cat food a", label: "Cat Food A" },
{ value: "cat food b", label: "Cat Food B" }
];
假设我的 FieldArray 索引为 0:
<Select
name={`petType.${index}`}
options={petListOptions}
value={dog}
/>
基于 Pet Type
selection of dog
然后我如何设置以下 select
以在索引 0 处具有 dogFood
的选项,即:
<Select
name={`petFood.${index}`}
options={dogFood}
/>
现在如果用户在 FieldArray 中添加另一行,现在在索引 1 和现在 select cat
,我如何设置选项现在在索引 1 使用 catFood
?
<Select
name={`petType.${index}`}
options={petListOptions}
value={cat}
/>
<Select
name={`petFood.${index}`}
options={catFood}
/>
我不确定如何根据我的 FieldArray 中的宠物列表 selection 在各种索引处设置这些宠物食品选项。
因此,为了正确理解,您必须呈现一个控件列表,一个选择哪种类型的宠物,然后根据第一个选择,程序呈现可供选择的食物选项。
const petListOptions = [
{ value: "dog", label: "Dog" },
{ value: "cat", label: "Cat" }
];
从第一个列表中选择的值将决定接下来要呈现的选项。因此,为了便于检索,我保留了下面的 petFood 数组的键,以匹配从上面的第一个选择返回的一组可能值。
const petFood = {
dog: [
{ value: "dog food choice a", label: "Dog Food A" },
{ value: "dog food choice b", label: "Dog Food B" }
],
cat: [
{ value: "cat food a", label: "Cat Food A" },
{ value: "cat food b", label: "Cat Food B" }
]
};
为了保存 petType 和 petFood 的值,我们传递了一个数组,其中第一个对象已初始化,其中 petType 和 food 属性都设置为空。 这将只呈现一组行。
在下面的代码中:<Field name={
petSelection.${index}.petType} as="select" value={selectedPet.petType}> ... </Field>
告诉 formik 如何存储选择的值。
注意 FieldArray 上的 name
属性。您要存储值的 属性 应该是 FieldArray's name <dot> Index
。如果我们想将我们的值放在特定的 属性 中,我们可以将 <dot> Property name
附加到我们的 Select 字段的名称。
export const PetsList = () => (
<div>
<h1>Pet List</h1>
<Formik
initialValues={{
petSelection: [
{
petType: "",
petFood: ""
}
]
}}
onSubmit={(values) =>
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
}, 500)
}
render={({ values }) => (
<Form>
<FieldArray
name="petSelection"
render={(arrayHelpers) => (
<div>
{values.petSelection && values.petSelection.length > 0 ? (
values.petSelection.map((selectedPet, index) => {
//console.log("selectedPet" + index, selectedPet);
return (
<div key={index}>
<Field
name={`petSelection.${index}.petType`}
as="select"
value={selectedPet.petType}
>
<option value="" disabled />
{petListOptions.map((pet, petIndex) => (
<option value={pet.value}>{pet.label}</option>
))}
</Field>
{selectedPet.petType && (
<Field
name={`petSelection.${index}.petFood`}
as="select"
value={selectedPet.petFood}
>
<option value="" disabled />
{petFood[selectedPet.petType].map(
(food, foodIndex) => (
<option value={food.value}>{food.label}</option>
)
)}
</Field>
)}
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a friend from the list
>
-
</button>
<button
type="button"
onClick={() =>
arrayHelpers.insert(index, {
petType: "",
petFood: ""
})
} // insert an new object at a position
>
+
</button>
</div>
);
})
) : (
<button
type="button"
onClick={() => arrayHelpers.push({
petType: "",
petFood: ""
})}>
{/* show this when user has removed all pets from the list */}
Add a Pet
</button>
)}
<div>
<button type="submit">Submit</button>
</div>
</div>
)}
/>
</Form>
)}
/>
</div>
);
添加按钮只是将一个新对象添加到 petsSelection
数组,属性 petType
和 petFood
初始化为空字符串。
现在,在您进行选择的任何行中,您一定要将值添加到这个新对象!