我有一个这样的表格:-
import Drawer from "components/atoms/Drawer";
/* import Input from "components/atoms/Input";
import InputGroup from "components/atoms/InputGroup";
import Label from "components/atoms/Label"; */
import Scrim from "components/atoms/Scrim";
import DrawerBody from "components/molecules/DrawerBody";
import { Field, FieldArray, Form, FormikErrors, FormikProps, withFormik } from "formik";
import { ITrackedPage } from "hocs/withAppDynamics";
import * as React from "react";
import { Box, Flex, Text } from "rebass";
import * as AmenitiesActions from "store/amenities/actions";
import { IAmenity, IAmenityRanking } from "store/amenities/models";
import DrawerHeader from "./DrawerHeader";
// import ErrorMessage from 'components/atoms/ErrorMessage';
interface IAmenitiesDrawerProps {
drawerOpen: boolean;
onDrawerClose: () => void;
tenantAssessmentId: string;
actions: typeof AmenitiesActions;
maxRank?: number;
}
interface IAmenitiesDrawerValues {
amenitieslist: IAmenity[];
}
const InnerForm: React.FC<
IAmenitiesDrawerProps & ITrackedPage & FormikProps<IAmenitiesDrawerValues>
> = ({
errors,
drawerOpen,
onDrawerClose,
handleChange,
values,
setValues,
isValid,
tenantAssessmentId,
sendAnalyticsData,
actions
}) => {
const handleDrawerClose = () => {
onDrawerClose();
};
return (
<>
<Scrim isOpen={drawerOpen} onClose={handleDrawerClose} />
<Drawer isOpen={drawerOpen} direction="right" drawerWidth="700px">
<DrawerHeader handleCloseDrawer={handleDrawerClose} />
<DrawerBody p={5}>
<Flex mb={4}>
<Box flex={1}>
<Text fontWeight="light" fontSize={4} mt={3} mb={4}>
Add custom amenities
</Text>
</Box>
</Flex>
<Form>
<FieldArray
name="amenitieslist"
render={arrayHelpers => (
<div>
{// values.amenitieslist && values.amenitieslist.length > 0 ? (
values.amenitieslist.map((amenity, index) => (
<div key={index}>
<Field name={`amenitieslist.${index}.name`} />
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a amenity from the list
>
-
</button>
{errors.amenitieslist}
</div>
))}
<button type="button" onClick={() => arrayHelpers.push({ id: "", name: "", imageUrl: '', description: '', tenantAssessmentId })}>
{/* show this when user has removed all amenities from the list */}
Add a Amenity
</button>
</div>
)}
/>
<div>
<button type="submit">Submit</button>
</div>
</Form>
</DrawerBody>
</Drawer>
</>
);
};
export const AmenitiesDrawer = withFormik<IAmenitiesDrawerProps, IAmenitiesDrawerValues>({
enableReinitialize: true,
handleSubmit: (values, {props}) => {
const seed: number = props.maxRank? props.maxRank : 0;
const amenityRankings: IAmenityRanking[] = values.amenitieslist.map((a, index)=>({
amenityId: 1,
rank: index + 1 + seed,
amenityName: a.name,
customAmenity: true
}));
console.log(amenityRankings);
console.log(props.actions.customSaveAmenities);
console.log(props.tenantAssessmentId);
props.actions.customSaveAmenities(props.tenantAssessmentId, amenityRankings);
},
mapPropsToValues: ({tenantAssessmentId}) => ({
amenitieslist:[{id: 0, name: '', imageUrl: '', description: '', tenantAssessmentId}]
}),
validate: values => {
const errors: FormikErrors<{ validAmenity: string }> = {};
console.log('In the Validate method');
const { amenitieslist } = values;
const amenityValid = amenitieslist[0].name.length < 28;
if (!amenityValid) {
console.log('Amenity is not valid');
errors.validAmenity = "Amenity needs to be atmost 28 characters";
console.log(errors);
}
return errors;
}
})(InnerForm);
大家都可以看到我有文本输入。当长度超过28个字符时,我想在文本字段下方抛出错误消息。
这怎么可能?请帮我解决一下这个。
答案 0 :(得分:0)
我发现验证Formik表单最方便的方法是按照文档中的建议使用yup。您可以定义一个验证模式,并将其作为道具传递给主要的Formik组件(或您正在使用的HOC),并删除自定义验证功能:
validationSchema: yup.object().shape({
amenitieslist: yup.array()
.of(yup.object().shape({
name: yup.string().max(28, "Max 28 chars")
// Rest of your amenities object properties
}))
})
然后在您的FieldArray
中:
<FieldArray
name="amenitieslist"
render={arrayHelpers => (
<div>
{// values.amenitieslist && values.amenitieslist.length > 0 ? (
values.amenitieslist.map((amenity, index) => (
<div key={index}>
<Field name={`amenitieslist[${index}].name`} />
<button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove a amenity from the list
>
-
</button>
{errors.amenitieslist[index].name}
</div>
))}
<button type="button" onClick={() => arrayHelpers.push({ id: "", name: "", imageUrl: '', description: '', tenantAssessmentId })}>
{/* show this when user has removed all amenities from the list */}
Add a Amenity
</button>
</div>
)}
/>
我只是更改了用于指定字段名称的访问器(要对数组元素使用索引,必须使用方括号表示法),并且在哪里可以找到错误,yup应该自动生成它们。很难确定我不会在不进行测试的情况下错过任何东西,希望这会有所帮助!