0Pricing
React Native Academy · 강의

Controller로 react-hook-form 설정하기

react-hook-form을 설치하고 useForm으로 양식 인스턴스를 만든 다음, 각 TextInput을 Controller로 감싸 등록하고 onChange/onBlur를 받습니다.

Controller로 react-hook-form 설정하기은(는) CoddyKit의 무료 React Native Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Native Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Why react-hook-form?

react-hook-form is a performant, flexible library for building forms in React and React Native. Unlike manually wiring every input to useState, react-hook-form uses uncontrolled inputs to minimize re-renders. It integrates validation, error handling, and form submission into a single coherent API, and it works seamlessly with any UI component library through the Controller wrapper.

Installing react-hook-form

Install react-hook-form from npm. It has no dependencies and works with any React version 16.8+. No special configuration is needed — import its hooks and components directly into your React Native components after installation.

npm install react-hook-form

Creating a Form Instance with useForm

Call useForm() at the top of your component to create a form instance. It returns several utilities: control (for wiring inputs via Controller), handleSubmit (for form submission), formState.errors (for displaying validation errors), and reset (to clear all fields). Pass default values to useForm to pre-populate the form.

import { useForm } from 'react-hook-form';

interface LoginForm {
  email: string;
  password: string;
}

export default function LoginScreen() {
  const {
    control,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm<LoginForm>({
    defaultValues: { email: '', password: '' },
  });
}

Wrapping TextInput with Controller

In React Native, inputs are controlled components that need to be wrapped in Controller so react-hook-form can manage their values. Pass the control object, the field name, and a render prop. The render prop receives field which contains value, onChange, and onBlur to wire to the TextInput.

import { Controller } from 'react-hook-form';

<Controller
  control={control}
  name='email'
  render={({ field: { onChange, onBlur, value } }) => (
    <TextInput
      value={value}
      onChangeText={onChange}
      onBlur={onBlur}
      placeholder='Email'
      keyboardType='email-address'
      autoCapitalize='none'
    />
  )}
/>

Adding Validation Rules

Pass a rules prop to Controller to define validation constraints. The required rule marks a field as mandatory, minLength enforces a minimum character count, maxLength caps input length, and pattern validates against a regex. Each rule takes an object with a value and a message string shown when the rule fails.

<Controller
  control={control}
  name='email'
  rules={{
    required: { value: true, message: 'Email is required' },
    pattern: {
      value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
      message: 'Enter a valid email address',
    },
  }}
  render={({ field: { onChange, onBlur, value } }) => (
    <TextInput value={value} onChangeText={onChange} onBlur={onBlur} />
  )}
/>

Displaying Field Errors

After Controller validates a field, any error is available in formState.errors[fieldName]. Access its message property and render it below the input in a red Text component. Errors only appear after the field has been touched (onBlur) or after the first submit attempt, preventing premature error messages.

<Controller
  control={control}
  name='email'
  rules={{ required: 'Email is required' }}
  render={({ field: { onChange, onBlur, value } }) => (
    <View>
      <TextInput
        value={value}
        onChangeText={onChange}
        onBlur={onBlur}
        style={[styles.input, errors.email && styles.inputError]}
      />
      {errors.email && (
        <Text style={styles.errorText}>{errors.email.message}</Text>
      )}
    </View>
  )}
/>

Handling Form Submission with handleSubmit

Wrap your submit handler with handleSubmit. react-hook-form will run all validation rules first; if any field is invalid, it populates formState.errors and does not call your handler. If all fields are valid, your handler receives a typed object containing all field values — ready to send to an API.

async function onSubmit(data: LoginForm) {
  console.log('Submitting:', data.email, data.password);
  try {
    await authApi.login(data.email, data.password);
    navigation.replace('Home');
  } catch (err) {
    Alert.alert('Login Failed', 'Invalid email or password.');
  }
}

<Button title='Log In' onPress={handleSubmit(onSubmit)} />

Password Field Configuration

For password fields, set secureTextEntry to hide the typed characters and configure an appropriate keyboard type. Wire the field to Controller exactly like the email field. Many apps also add a 'show/hide' icon button that toggles secureTextEntry via local state — this improves accessibility for users with typos.

<Controller
  control={control}
  name='password'
  rules={{
    required: 'Password is required',
    minLength: { value: 8, message: 'Password must be at least 8 characters' },
  }}
  render={({ field: { onChange, onBlur, value } }) => (
    <TextInput
      value={value}
      onChangeText={onChange}
      onBlur={onBlur}
      secureTextEntry
      placeholder='Password'
    />
  )}
/>

Using watch to Observe Field Values

The watch function returned by useForm lets you subscribe to a field's current value and react to changes in real time. A common use case is a 'confirm password' field that validates its value matches the password field. Pass a field name to watch and use the returned value in the confirm field's validate rule.

const { control, handleSubmit, watch, formState: { errors } } = useForm<RegisterForm>();
const password = watch('password');

<Controller
  control={control}
  name='confirmPassword'
  rules={{
    validate: (value) =>
      value === password || 'Passwords do not match',
  }}
  render={({ field }) => <TextInput {...field} secureTextEntry />}
/>

Resetting the Form

Call reset() to clear all field values and errors, returning the form to its default values. You can also pass a new set of values to reset({ email: 'prefilled@example.com' }) to re-initialize the form with different defaults, which is useful for edit-profile forms that pre-populate with existing user data.

// Clear after successful submit:
async function onSubmit(data: LoginForm) {
  await api.login(data);
  reset(); // clears all inputs
}

// Pre-fill with existing profile data:
useEffect(() => {
  if (userProfile) {
    reset({
      name: userProfile.name,
      email: userProfile.email,
    });
  }
}, [userProfile]);

Form Validation Modes

react-hook-form offers several mode settings that control when validation runs: 'onSubmit' (default, validates only on submit), 'onBlur' (validates when a field loses focus), 'onChange' (validates on every keystroke), and 'all' (combines onBlur and onChange). For mobile forms, 'onBlur' offers the best balance between immediate feedback and avoiding distracting errors while typing.

const { control, handleSubmit } = useForm<LoginForm>({
  mode: 'onBlur',       // validate when user leaves a field
  defaultValues: { email: '', password: '' },
});

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: useForm creates the form instance with control, handleSubmit, and formState.errors, Controller wires native TextInput components to the form with onChange, onBlur, and value props, and rules define built-in validation constraints that populate errors automatically. Next up we explore validation rules and error message handling in depth.

자주 묻는 질문

“Controller로 react-hook-form 설정하기” 강의는 무료인가요?

네 — “Controller로 react-hook-form 설정하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Native Academy 강의 전체를 잠금 해제할 수 있습니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Controller로 react-hook-form 설정하기”에서 뭘 배우나요?

react-hook-form을 설치하고 useForm으로 양식 인스턴스를 만든 다음, 각 TextInput을 Controller로 감싸 등록하고 onChange/onBlur를 받습니다. 브라우저에서 직접 실행하는 실습 코드로 React Native Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Native Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Native Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“Controller로 react-hook-form 설정하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Native Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Native Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Controller로 react-hook-form 설정하기
  2. 검증 규칙과 오류 메시지
  3. 양식 상태를 활용한 다단계 양식
  4. 양식 제출 및 초기화
← React Native Academy(으)로 돌아가기