Forms play a very crucial role in any app. They are the portal through which the user submits data. So building scalable forms becomes a very important task.
Every form has three main aspects that need to be addressed:
Handling these aspects all by yourself can be a little tedious and overwhelming. So using a third-party package would be a wise decision. Now there are two main packages that people recommend for form - Redux Forms and Formik. We will be using Formik as saving form states in redux seems overkill.
We will be using Magnus for making inputs and yup for creating validation schemas.
yarn add color react-native-animatable react-native-modal react-native-vector-icons formik yup
Make sure you install pods after installing these dependencies.
import * as React from "react";
import { AppRegistry } from "react-native";
import { ThemeProvider, Text } from "react-native-magnus";
const theme = {
fontSize: {
bigText100: 40,
},
};
export default function Main() {
return (
<ThemeProvider theme={theme}>
<Text>Hello World</Text>
</ThemeProvider>
);
}
AppRegistry.registerComponent("main", () => Main);
Let’s first create the inputs using Magnus
import * as React from "react";
import { AppRegistry, SafeAreaView } from "react-native";
import { ThemeProvider, Text, Button, Input } from "react-native-magnus";
export default function Main() {
return (
<ThemeProvider>
<SafeAreaView style={{ flex: 1 }}>
<Div m="lg">
<Text mt="2xl" color="gray900" fontWeight="bold" fontSize="2xl">
Login
</Text>
<Text color="gray500" mt="sm">
Lorem ipsum dolor sit, amet consectetur.
</Text>
<Text fontSize="md" color="gray600" mt="2xl">
Email
</Text>
<Input
mt="sm"
py="lg"
placeholder="Email Address"
autoCapitalize={false}
/>
<Text fontSize="md" color="gray600" mt="xl">
Password
</Text>
<Input mt="sm" py="lg" placeholder="Password" secureTextEntry />
<Button block py="lg" mt="xl">
Submit
</Button>
</Div>
</SafeAreaView>
</ThemeProvider>
);
}
<Div m="lg">
Div
is a wrapper around View
provided by Magnus. Since it’s a wrapper around View
of react-native, it accepts all props that are supported by View. Being a Magnus component, it has all the utility magic ( spacing, border-radius, colors, etc). Here we are proving margin on all sides with value lg
which is evaluated to 12.
You can see more about this spacing utilities here - https://magnus-ui.com/docs/spacing
import * as React from "react";
import { Formik } from "formik";import { AppRegistry, SafeAreaView } from "react-native";
import { ThemeProvider, Text, Button, Input } from "react-native-magnus";
export default function Main() {
return (
<ThemeProvider>
<SafeAreaView style={{ flex: 1 }}>
<Div m="lg">
<Formik initialValues={{ email: "", password: "", }} onSubmit={() => {}} > {(props) => {
return <>...</>;
}}
</Formik> </Div>
</SafeAreaView>
</ThemeProvider>
);
}
Now let’s integrate our input and submit button with Formik.
...
<SafeAreaView style={{ flex: 1 }}>
<Div m="lg">
<Formik
initialValues={{
email: "",
password: "",
}}
onSubmit={this.onSubmit}
validationSchema={loginValidator}
>
{props => {
const { values, status, touched, errors, isSubmitting, handleChange, handleBlur, handleSubmit, } = props;
return (
<>
<Text
mt="2xl"
color="gray900"
fontWeight="bold"
fontSize="bigText100"
>
Login
</Text>
<Text color="gray500" mt="sm">
Lorem ipsum dolor sit, amet consectetur.
</Text>
<Text fontSize="md" color="gray600" mt="2xl">
Email
</Text>
<Input
mt="sm"
py="lg"
placeholder="Email Address"
autoCapitalize={false}
value={values.email}
onChangeText={handleChange("email")} onBlur={handleBlur("email")} />
<Text fontSize="md" color="gray600" mt="xl">
Password
</Text>
<Input
mt="sm"
py="lg"
placeholder="Password"
secureTextEntry
value={values.password}
onChangeText={handleChange("password")} onBlur={handleBlur("password")}
/>
<Button
block
py="lg"
mt="xl"
onPress={handleSubmit} loading={isSubmitting} >
Submit
</Button>
</>
);
}}
</Formik>
</Div>
</SafeAreaView>
On line 13, We deconstructed some props provided by Formik. Here is what those props are meant for:
There are many more props provided by formik that you can read about more here - https://jaredpalmer.com/formik/docs/api/formik
Now we have our form and inputs rendered, Let’s start with the form validation. This is where Yup is needed. We chose yup for two reason
Import it at the top.
import * as React from "react";
import { Formik } from "formik";
import { AppRegistry, SafeAreaView } from "react-native";
import { ThemeProvider, Text, Button, Input } from "react-native-magnus";
import * as Yup from "yup";
Now let’s create our validation schema for our login form.
export const loginValidator = yup.object().shape({
email: yup.string().min(1).required().email(),
password: yup.string().min(6).required().max(255),
});
Formik accepts a special prop called validationSchema
to which we can pass yup schema object and Formik will handle validation for us.
// ...
<Formik
initialValues={{
email: '',
password: '',
}}
onSubmit={() => {}}
validationSchema={loginValidator}>
That’s it. Yup is integrated with Formik now.
Since we have our Formik form integrated with yup schema, we can easily render out field error messages. All of our field errors are stored in errors object.
...
<Input
mt="sm"
py="lg"
placeholder="Email Address"
autoCapitalize={false}
value={values.email}
onChangeText={handleChange('email')}
onBlur={handleBlur('email')}
/>
<Div h={20}> <Div position="absolute" top={0} zIndex={1}> <Text color="red500" fontSize="md" mt="sm"> {touched.email && errors.email} </Text> </Div> </Div>
<Text fontSize="md" color="gray600" mt="xl">
Password
</Text>
<Input
mt="sm"
py="lg"
placeholder="Password"
secureTextEntry
value={values.password}
onChangeText={handleChange('password')}
onBlur={handleBlur('password')}
/>
<Div h={20}> <Div position="absolute" top={0} zIndex={1}> <Text color="red500" fontSize="md" mt="sm"> {touched.password && errors.password} </Text> </Div> </Div>...
setSubmitting
prop.setStatus
prop.Copyright © Magnus UI 2020