Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: react-hook-form example #496

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions with-react-hook-form/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { View, Text, StyleSheet, TextInput, Button } from "react-native";
import { useForm, Controller } from "react-hook-form";

const EMAIL_REGEX = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/;

export default function App() {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: {
email: "",
password: "",
},
});

const onSubmit = (values) => {
const { email, password } = values;

alert(`Email: ${email}, Password: ${password}`);
};

return (
<View style={styles.container}>
<Text style={styles.label}>Email</Text>
<Controller
name="email"
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
placeholder="Email"
onBlur={onBlur}
onChangeText={onChange}
value={value}
style={styles.textInput}
keyboardType="email-address"
autoCapitalize="none"
/>
)}
rules={{
required: "Email is required.",
pattern: {
value: EMAIL_REGEX,
message: "Enter a valid email address.",
},
}}
/>
{errors.email && <Text style={styles.error}>{errors.email.message}</Text>}

<Text style={styles.label}>Password</Text>
<Controller
name="password"
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
placeholder="Password"
onBlur={onBlur}
onChangeText={onChange}
value={value}
secureTextEntry
autoCapitalize="none"
style={styles.textInput}
/>
)}
rules={{
required: "Password is required.",
minLength: {
value: 6,
message: "Password must be at least 6 characters long.",
},
}}
/>
{errors.password && (
<Text style={styles.error}>{errors.password.message}</Text>
)}

<View style={styles.buttonContainer}>
<Button title="Submit" onPress={handleSubmit(onSubmit)} />
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
justifyContent: "center",
},
label: {
marginBottom: 8,
fontSize: 14,
fontWeight: "bold",
color: "#333",
},
textInput: {
height: 40,
borderColor: "#ccc",
borderWidth: 1,
borderRadius: 4,
paddingHorizontal: 8,
marginBottom: 16,
backgroundColor: "#fff",
},
error: {
color: "red",
marginBottom: 12,
},
buttonContainer: {
marginTop: 24,
borderRadius: 4,
},
});
51 changes: 51 additions & 0 deletions with-react-hook-form/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# React Hook Form Example

<p>
<!-- iOS -->
<a href="https://itunes.apple.com/app/apple-store/id982107779">
<img alt="Supports Expo iOS" longdesc="Supports Expo iOS" src="https://img.shields.io/badge/iOS-4630EB.svg?style=flat-square&logo=APPLE&labelColor=999999&logoColor=fff" />
</a>
<!-- Android -->
<a href="https://play.google.com/store/apps/details?id=host.exp.exponent&referrer=blankexample">
<img alt="Supports Expo Android" longdesc="Supports Expo Android" src="https://img.shields.io/badge/Android-4630EB.svg?style=flat-square&logo=ANDROID&labelColor=A4C639&logoColor=fff" />
</a>
<!-- Web -->
<a href="https://docs.expo.dev/workflow/web/">
<img alt="Supports Expo Web" longdesc="Supports Expo Web" src="https://img.shields.io/badge/web-4630EB.svg?style=flat-square&logo=GOOGLE-CHROME&labelColor=4285F4&logoColor=fff" />
</a>
</p>

This example demonstrates how to integrate [React Hook Form](https://react-hook-form.com/) with Expo, helping you write less code and avoid unnecessary re-renders for improved performance.

![Example in action](https://github.com/user-attachments/assets/9f076ed9-3500-41df-8f90-f034cc3c7626)

## 🚀 How to use

Execute [`create-expo`](https://github.com/expo/expo/tree/main/packages/create-expo) with [npm](https://docs.npmjs.com/cli/init), [yarn](https://yarnpkg.com/lang/en/docs/cli/create/), [pnpm](https://pnpm.io/cli/create), or [bun](https://bun.sh/docs/cli/bun-create) to bootstrap the example:

```bash
npx create-expo --example with-react-hook-form
```

```bash
yarn create expo --example with-react-hook-form
```

```bash
pnpm create expo --example with-react-hook-form
```

```bash
bun create expo --example with-react-hook-form
```

To run your project, navigate to the directory and start the dev server.

Open the project on your preferred platform:
- iOS: [Expo Go](https://itunes.apple.com/app/apple-store/id982107779)
- Android: [Expo Go](https://play.google.com/store/apps/details?id=host.exp.exponent&referrer=blankexample)
- Web: Any web browser

## 📝 Notes

- Learn more about [React Hook Form](https://react-hook-form.com/)
6 changes: 6 additions & 0 deletions with-react-hook-form/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
20 changes: 20 additions & 0 deletions with-react-hook-form/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "~3.2.1",
"expo": "^51.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.52.1",
"react-native": "0.74.1",
"react-native-web": "~0.19.6"
},
"devDependencies": {
"@babel/core": "^7.19.3"
}
}