Регистрация не является функцией при передаче в качестве реквизита?

avatar
KukuBra
8 августа 2021 в 17:44
1338
2
1

Я впервые использую форму react-hook. Я читал документы и следовал за ними. Точно так же я уже разложил свои компоненты и стилизовал их. Теперь я пытаюсь предупредить данные после отправки формы.

Это ContactForm

import React, { useState } from 'react';
import * as S from './style';
import { PrimaryButton } from '@element/Button';
import TextInput from '@element/TextInput';
import { useForm } from 'react-hook-form';

export const ContactForm = () => {
  const { register, handleSubmit } = useForm();
  const [firstName, setFirstName] = useState('');
  const onSubmit = (data) => {
    alert(JSON.stringify(data));
  };
return (
    <S.ContactFormWrapper onSubmit={handleSubmit(onSubmit)}>
      <TextInput
        name={'firstName'}
        label={'First Name'}
        state={firstName}
        setState={setFirstName}
        placeholder={'John'}
        type={'text'}
        width={'48%'}
        options={{
          maxLength: '20',
          minLength: '2',
          required: true,
        }}
        register={register}
      />
      <PrimaryButton type={'submit'} text={'Send Message'} />
    </S.ContactFormWrapper onSubmit={handleSubmit(onSubmit)}>
)
}

Это мой заказ, созданный TextInput

import React, { useEffect, useState } from 'react';
import * as S from './style';

const TextInput = ({
  name,
  label,
  placeholder,
  state,
  setState,
  type,
  width,
  register,
  options,
}) => {
  const [isActive, setIsActive] = useState(false);

  return (
    <S.TextInputWrapper inputWidth={width}>
      <S.Label htmlFor={name} isActive={isActive}>
        {label}
      </S.Label>
      <S.Input
        placeholder={placeholder}
        type={type}
        name={name}
        id={name}
        {...register(name, options)}
        onChange={(event) => setState(event.target.value)}
        onFocus={() => setIsActive(true)}
        onBlur={() => setIsActive(false)}
      />
    </S.TextInputWrapper>
  );
};

export default TextInput;

Сообщение об ошибке

TypeError: register is not a function {...register(name, options)}

Я искал в StackOverflow сообщение, но ответ меня сбил с толку, а код спрашивающего сильно отличался от моего. Потому что я думаю, что ошибка произошла из-за того, что я использую стилизованные компоненты, и они глубоко вложены. Я в замешательстве, потому что читал документы и следил за ними.

Если я распространяю сообщение об ошибке, register is not a function иначе, если я не распространяю его, то возникает ошибка ... spread is required.

Надеюсь, вы сможете пролить свет на мое замешательство.

С уважением Куку

Источник

Ответы (2)

avatar
Joris
8 августа 2021 в 19:42
0

useFormContext — хорошее решение, объясненное @Sean W

Вот еще одно решение без useFormContext, вы можете использовать register как обычно вместо того, чтобы передавать его в качестве опоры. Вам просто нужно переслать ссылку вашего TextInput.

????????? Вы можете найти пример здесь: https://coderhelper.com/a/68667226/4973076

avatar
Sean W
8 августа 2021 в 18:56
2

Самое простое решение состоит в том, чтобы воспользоваться преимуществами контекста формы хука реакции и использовать хук useFormContext.

Компонент ввода

import { useFormContext } from "react-hook-form";

const TextInput = ({ name, options }) => {  
  const { register } = useFormContext();
  return (
      <S.Input
        name={name}
        {...register(name, options)}
      />
    </S.TextInputWrapper>
  );
};

Удалить функцию ввода register из родительской формы

export const ContactForm = () => {
 ...other functions
 return <TextInput name={'firstName'} options={{maxLength: '20' }} />;
}

Еще более простое решение состоит в том, чтобы позволить react-hook-form управлять значениями формы и использовать хук useController или компонент Controller.

import { useController } from "react-hook-form";
const TextInput = ({ name, options }) => {  
  const { field } = useController({ name, rules: options });
  return <S.Input name={name} {...field} />
};

Вы также можете получить состояния ввода с помощью хука useContoller, чтобы уменьшить количество используемых вами событий.

import { useController } from "react-hook-form";
const TextInput = ({ name, options }) => {  
  const { 
   field,
   fieldState: { error, invalid, isDirty, isTouched }
 } = useController({ name, rules: options });
};