Kodax

النماذج والتحقق — React Native المتقدم

النماذج في React Native

1. React Hook Form

npm install react-hook-form
import { useForm, Controller } from 'react-hook-form';

function LoginForm() {
  const { control, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
      email: '',
      password: '',
    }
  });

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <View style={styles.form}>
      <Controller
        control={control}
        name="email"
        rules={{
          required: 'البريد مطلوب',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: 'بريد غير صالح'
          }
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            placeholder="البريد الإلكتروني"
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
            keyboardType="email-address"
            autoCapitalize="none"
            style={[styles.input, errors.email && styles.inputError]}
          />
        )}
      />
      {errors.email && <Text style={styles.error}>{errors.email.message}</Text>}

      <Controller
        control={control}
        name="password"
        rules={{
          required: 'كلمة المرور مطلوبة',
          minLength: {
            value: 6,
            message: 'يجب أن تكون 6 أحرف على الأقل'
          }
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            placeholder="كلمة المرور"
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
            secureTextEntry
            style={[styles.input, errors.password && styles.inputError]}
          />
        )}
      />
      {errors.password && <Text style={styles.error}>{errors.password.message}</Text>}

      <TouchableOpacity 
        onPress={handleSubmit(onSubmit)}
        style={styles.button}
      >
        <Text style={styles.buttonText}>تسجيل الدخول</Text>
      </TouchableOpacity>
    </View>
  );
}

2. Yup للتحقق

npm install yup @hookform/resolvers
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';

const schema = yup.object({
  name: yup.string()
    .required('الاسم مطلوب')
    .min(2, 'الاسم قصير جداً'),
  email: yup.string()
    .required('البريد مطلوب')
    .email('بريد غير صالح'),
  password: yup.string()
    .required('كلمة المرور مطلوبة')
    .min(8, 'يجب 8 أحرف على الأقل')
    .matches(/[A-Z]/, 'يجب أن تحتوي على حرف كبير')
    .matches(/[0-9]/, 'يجب أن تحتوي على رقم'),
  confirmPassword: yup.string()
    .oneOf([yup.ref('password')], 'كلمات المرور غير متطابقة'),
  age: yup.number()
    .required('العمر مطلوب')
    .min(18, 'يجب أن تكون 18 سنة أو أكثر')
    .max(100, 'عمر غير صالح'),
  phone: yup.string()
    .matches(/^07[0-9]{9}$/, 'رقم هاتف عراقي غير صالح'),
}).required();

function RegisterForm() {
  const { control, handleSubmit, formState: { errors, isSubmitting } } = useForm({
    resolver: yupResolver(schema),
    mode: 'onBlur', // التحقق عند مغادرة الحقل
  });

  return null; // الحقول مع Controller في المثال التالي
}

3. مكون Input قابل لإعادة الاستخدام

function FormInput({
  control,
  name,
  label,
  rules,
  error,
  secureTextEntry,
  ...rest
}) {
  const [showPassword, setShowPassword] = useState(false);

  return (
    <View style={styles.inputContainer}>
      {label && <Text style={styles.label}>{label}</Text>}
      
      <Controller
        control={control}
        name={name}
        rules={rules}
        render={({ field: { onChange, onBlur, value } }) => (
          <View style={styles.inputWrapper}>
            <TextInput
              onBlur={onBlur}
              onChangeText={onChange}
              value={value}
              secureTextEntry={secureTextEntry && !showPassword}
              style={[styles.input, error && styles.inputError]}
              {...rest}
            />
            {secureTextEntry && (
              <TouchableOpacity
                onPress={() => setShowPassword(!showPassword)}
                style={styles.eyeIcon}
              >
                <Ionicons
                  name={showPassword ? 'eye-off' : 'eye'}
                  size={24}
                  color="#888"
                />
              </TouchableOpacity>
            )}
          </View>
        )}
      />
      
      {error && (
        <Animated.Text 
          entering={FadeInDown}
          style={styles.errorText}
        >
          {error.message}
        </Animated.Text>
      )}
    </View>
  );
}

// الاستخدام
<FormInput
  control={control}
  name="email"
  label="البريد الإلكتروني"
  error={errors.email}
  keyboardType="email-address"
  autoCapitalize="none"
/>
اختبر فهمك