将 formik 与 typescript (Ionic) 结合使用
Using formik with typescript (Ionic)
我尝试使用 Formik 库来验证表单,但是我无法将 onChange 函数传递给我的输入组件。
这里是主要成分:
import React from 'react';
import { IonHeader, IonContent, IonToolbar, IonTitle, IonButton, IonPage, IonList } from '@ionic/react';
import { useFormik } from 'formik';
import BasicInput from '../components/form/BasicInput';
const Login: React.FC = () => {
const validate = (values: {
name: string;
}) => {
const errors = {};
if (!values.name) {
}
return errors;
}
const formik = useFormik({
initialValues: {
name: ''
},
validateOnChange: false,
validateOnBlur: false,
validate,
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
})
const {
name
} = formik.values
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Login</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonList>
<BasicInput
id="name"
placeholder={"Your name"}
onChange={formik.handleChange}
/>
</IonList>
<div>
<IonButton onClick={handleLogin}>
Done
</IonButton>
</div>
</IonContent>
</IonPage>
)
}
export default Login;
这是我的输入组件:
import React from 'react';
import { IonInput, IonItem } from '@ionic/react';
const BasicInput: React.FC<{
id: string,
placeholder: string,
onChange: () => any
}> = (props) => {
return (
<IonItem>
<IonInput
placeholder={props.placeholder}
onIonChange={props.onChange}
>
</IonInput>
</IonItem>
)
}
export default BasicInput;
我收到的错误是 "Type '(eventOrPath: string | ChangeEvent) => void | ((eventOrTextValue: string | ChangeEvent) => void)' is not assignable to type '() => any'." 在我的 onChange 道具上。
如何正确申报TS?
消息指出问题所在。
在 BasicInput
中,您正在定义一个道具 onChange: () => any
。但很明显,要调用的函数需要接收新的输入值作为参数,不需要 return 任何东西,所以你的 prop 定义应该是这样的:
{
// ...
onChange: (newValue: string) => void;
}
但是,如果您将鼠标悬停在 <IonInput />
的 onIonChange
属性上,您会看到传递的函数没有接收字符串作为参数!
它实际上触发了 CustomEvent。有了这个事件 e
,您可以通过 e.target.value
.
访问输入值
完整代码变成这样:
import React from 'react';
import { IonInput, IonItem } from '@ionic/react';
const BasicInput: React.FC<{
id: string,
placeholder: string,
onChange: (newValue: string) => void
}> = (props) => {
return (
<IonItem>
<IonInput
placeholder={props.placeholder}
onIonChange={(e) => props.onChange(e.target.value)}
>
</IonInput>
</IonItem>
)
}
export default BasicInput;
我尝试使用 Formik 库来验证表单,但是我无法将 onChange 函数传递给我的输入组件。
这里是主要成分:
import React from 'react';
import { IonHeader, IonContent, IonToolbar, IonTitle, IonButton, IonPage, IonList } from '@ionic/react';
import { useFormik } from 'formik';
import BasicInput from '../components/form/BasicInput';
const Login: React.FC = () => {
const validate = (values: {
name: string;
}) => {
const errors = {};
if (!values.name) {
}
return errors;
}
const formik = useFormik({
initialValues: {
name: ''
},
validateOnChange: false,
validateOnBlur: false,
validate,
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
})
const {
name
} = formik.values
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Login</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonList>
<BasicInput
id="name"
placeholder={"Your name"}
onChange={formik.handleChange}
/>
</IonList>
<div>
<IonButton onClick={handleLogin}>
Done
</IonButton>
</div>
</IonContent>
</IonPage>
)
}
export default Login;
这是我的输入组件:
import React from 'react';
import { IonInput, IonItem } from '@ionic/react';
const BasicInput: React.FC<{
id: string,
placeholder: string,
onChange: () => any
}> = (props) => {
return (
<IonItem>
<IonInput
placeholder={props.placeholder}
onIonChange={props.onChange}
>
</IonInput>
</IonItem>
)
}
export default BasicInput;
我收到的错误是 "Type '(eventOrPath: string | ChangeEvent) => void | ((eventOrTextValue: string | ChangeEvent) => void)' is not assignable to type '() => any'." 在我的 onChange 道具上。
如何正确申报TS?
消息指出问题所在。
在 BasicInput
中,您正在定义一个道具 onChange: () => any
。但很明显,要调用的函数需要接收新的输入值作为参数,不需要 return 任何东西,所以你的 prop 定义应该是这样的:
{
// ...
onChange: (newValue: string) => void;
}
但是,如果您将鼠标悬停在 <IonInput />
的 onIonChange
属性上,您会看到传递的函数没有接收字符串作为参数!
它实际上触发了 CustomEvent。有了这个事件 e
,您可以通过 e.target.value
.
完整代码变成这样:
import React from 'react';
import { IonInput, IonItem } from '@ionic/react';
const BasicInput: React.FC<{
id: string,
placeholder: string,
onChange: (newValue: string) => void
}> = (props) => {
return (
<IonItem>
<IonInput
placeholder={props.placeholder}
onIonChange={(e) => props.onChange(e.target.value)}
>
</IonInput>
</IonItem>
)
}
export default BasicInput;