Forms Installation
This guide will walk you through installing and configuring Forms in your React Native project.
Installation
Install Forms using your preferred package manager:
Using npm
npm install @mapples/form
Using yarn
yarn add @mapples/form
Using pnpm
pnpm add @mapples/form
Basic Setup
1. Import Required Dependencies
Import the required Forms dependencies:
import React from 'react';
import { Form } from '@mapples/form';
2. Using the Form Component
Use the Form
component to wrap your form fields. The Form component handles FormProvider internally:
import React from 'react';
import { Form, useFormField } from '@mapples/form';
const LoginForm = () => {
const onSubmit = (data) => {
console.log('Form submitted:', data);
};
return (
<Form
initialValues={{ email: '', password: '' }}
onSubmit={onSubmit}
>
<EmailField />
<PasswordField />
</Form>
);
};
const EmailField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('email', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('email')}
placeholder="Email"
keyboardType="email-address"
autoCapitalize="none"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const PasswordField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('password', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('password')}
placeholder="Password"
secureTextEntry
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
Advanced Configuration
Custom Form Configuration
Create custom form configurations with extended validation and field handling:
import React from 'react';
import { Form, useFormField } from '@mapples/form';
const CustomForm = () => {
const onUpdate = (data) => {
console.log('Form updated:', data);
};
const onChange = (data) => {
console.log('Form changed:', data);
};
return (
<Form
initialValues={{ email: '', password: '' }}
historyItems={20}
historyItemThrottle={1}
onSubmit={onUpdate}
filterHistoryKeys={['_canvasProps']}
onChange={onChange}
>
<EmailField />
<PasswordField />
</Form>
);
};
TypeScript Configuration
For better TypeScript support, create a types file:
// types/forms.ts
import { FormContextType } from '@mapples/form';
export interface CustomFormData {
email: string;
password: string;
confirmPassword: string;
terms: boolean;
}
export interface CustomFormErrors {
email?: string;
password?: string;
confirmPassword?: string;
terms?: string;
}
export type CustomFormContext = FormContextType<CustomFormData, CustomFormErrors>;
Using Form Hooks
Basic Form Usage
Use the Form component for form state management:
import React from 'react';
import { View, TextInput, Button } from 'react-native';
import { Form, useFormField, useFormContext } from '@mapples/form';
const LoginForm = () => {
const onSubmit = (data) => {
console.log('Form submitted:', data);
};
return (
<Form
initialValues={{ email: '', password: '' }}
onSubmit={onSubmit}
>
<EmailField />
<PasswordField />
<SubmitButton />
</Form>
);
};
const EmailField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('email', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('email')}
placeholder="Email"
keyboardType="email-address"
autoCapitalize="none"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const PasswordField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('password', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('password')}
placeholder="Password"
secureTextEntry
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const SubmitButton = () => {
const { formState } = useFormContext();
return (
<Button
title="Submit"
onPress={() => {/* Form submission handled by Form component */}}
disabled={!formState.isValid}
/>
);
};
Using Form Validation
Use built-in validation with custom validators:
import React from 'react';
import { Form, useFormField, useFormContext } from '@mapples/form';
const RegistrationForm = () => {
const onSubmit = (data) => {
console.log('Registration data:', data);
};
return (
<Form
initialValues={{
firstName: '',
lastName: '',
email: '',
password: '',
confirmPassword: '',
}}
onSubmit={onSubmit}
>
<FirstNameField />
<LastNameField />
<EmailField />
<PasswordField />
<ConfirmPasswordField />
<SubmitButton />
</Form>
);
};
const FirstNameField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('firstName', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('firstName')}
placeholder="First Name"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const LastNameField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('lastName', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('lastName')}
placeholder="Last Name"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const EmailField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('email', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('email')}
placeholder="Email"
keyboardType="email-address"
autoCapitalize="none"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const PasswordField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('password', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('password')}
placeholder="Password"
secureTextEntry
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const ConfirmPasswordField = () => {
const {
value,
error,
setValue,
touch
} = useFormField('confirmPassword', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('confirmPassword')}
placeholder="Confirm Password"
secureTextEntry
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
};
const SubmitButton = () => {
const { submitForm } = useFormContext();
return (
<Button
title="Register"
onPress={submitForm}
/>
);
};
Integration with React Navigation
Multiple Forms in App
Each form should use its own Form component. Here's how to handle multiple forms in an app:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { Form } from '@mapples/form';
const App = () => {
return (
<NavigationContainer>
{/* Your navigation structure with individual forms */}
</NavigationContainer>
);
};
const LoginScreen = () => {
return (
<Form
initialValues={{ email: '', password: '' }}
onSubmit={(data) => console.log('Login:', data)}
>
<LoginForm />
</Form>
);
};
const RegisterScreen = () => {
return (
<Form
initialValues={{ name: '', email: '', password: '' }}
onSubmit={(data) => console.log('Register:', data)}
>
<RegisterForm />
</Form>
);
};
Performance Optimization
Memoization
Optimize your forms for better performance with memoization:
import React, { memo, useMemo } from 'react';
import { Form, useFormField } from '@mapples/form';
const ExpensiveForm = memo(({ initialData }) => {
const onSubmit = (data) => {
console.log('Form submitted:', data);
};
// Memoize expensive calculations
const processedData = useMemo(() => {
return initialData.map(item => ({
...item,
displayValue: item.value * 2,
}));
}, [initialData]);
return (
<Form
initialValues={{ name: '', email: '' }}
onSubmit={onSubmit}
>
<NameField />
<EmailField />
</Form>
);
});
const NameField = memo(() => {
const {
value,
error,
setValue,
touch
} = useFormField('name', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('name')}
placeholder="Name"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
});
const EmailField = memo(() => {
const {
value,
error,
setValue,
touch
} = useFormField('email', '');
return (
<View>
<TextInput
value={value || ''}
onChangeText={setValue}
onBlur={() => touch('email')}
placeholder="Email"
keyboardType="email-address"
autoCapitalize="none"
/>
{error && (
<Text style={{ color: 'red' }}>{error}</Text>
)}
</View>
);
});
Troubleshooting
Common Issues
Here are some common issues you might encounter:
- Form not updating: Ensure your app is wrapped with
FormProvider
- Validation not working: Check that your validation rules are correctly configured
- Fields not registering: Verify your field names match the form schema
- TypeScript errors: Make sure you have the correct type definitions imported
Debug Mode
Enable debug mode to see form processing:
const formConfig = {
debug: true, // Enable debug logging
validation: {
mode: 'onChange',
},
};