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

Como colocar o spreadoperator do register se meu input é um componente? #2

Open
maykelesser opened this issue May 17, 2022 · 2 comments

Comments

@maykelesser
Copy link

Seguindo o tutorial do Youtube, me deparei com uma situação: Se eu uso o input do HTML mesmo, funciona.
Porém, em meu front-end, eu utilizo um componente Input customizado. No fim, ele gera um HTML normal. Porém, quando passo o {...register('email')}, ao executar o handleSignIn, ele me retorna undefined.

Não sei como proceder, nem como colocar este spread para ser lido no meu componente.

<Input {...register('email')} autofocus='true' className='mb-3' size='md' type='email' name='email' placeholder={translation('content.form.login.placeholder')} />
<Input {...register('password')} className='mb-3' size='md' type='password' name='password' placeholder={translation('content.form.password.placeholder')} />
// * Render
export default function Input(props){

    console.log(props.ref);

    let inputClasses = '';

    // * Size
    if(props.size){
        switch(props.size){
            case 'md':
                inputClasses += ' input-md ';
            break;
            case 'lg':
                inputClasses += ' input-lg ';
            break;
            case 'xl':
                inputClasses += ' input-xl ';
            break;
        }
    }
    else{
        inputClasses += ' input-base ';
    }

    return (
        <div className='form-control'>
            <input onBlur={props.onBlur} className={inputClasses + props.className} onKeyPress={props.onKeyPress} onChange={props.onChange} type={props.type} defaultValue={props.value} name={props.name} min={props.min} max={props.max} placeholder={props.placeholder} required={props.required} />
            {((props.subtitle) ? <p>{props.subtitle}</p> : '')}
        </div>
    )
}
@lima-pedro
Copy link

lima-pedro commented Jun 3, 2022

Fala Mayk , beleza ?

Cara eu li teu comentário, e achei uma solução aqui. Não sei se é a melhor porém pra mim funcionou, vamos lá:

Primeiro criei um componente chamado InputEmail com o seguinte código:

export default function InputEmail({ register }) {
  return (
    <div>
      <label htmlFor="email-address" className="sr-only">
        Email address
      </label>

      <input
          {...register("email")}
          id="email-address"
          name="email"
          type="email"
          autoComplete="email"
          required
          className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
          placeholder="Email address"
        />
    </div>
  );
}

Eu realmente apenas copiei a div que já existia na index com o campo do e-mail, adicionei nele uma prop chamada register pra receber a função do useForm.

Em seguida eu usei esse componente lá na index e ai que vem o pulo do gato (rs) , coloquei a função register do useForm como uma props do componente:

<InputEmail register={ register } />

Dessa forma, quando lá no componente o dado for alterado, executa o register do useForm que está lá na index.

Lá no seu código ao invés de fazer o spread direto no componente customizado "Input", você coloca um nome pra props:

<Input inputRegister={register} autofocus='true' className='mb-3' size='md' type='email' name='email' placeholder={translation('content.form.login.placeholder')} />

Dai no seu componente customizado vc recebe props.inputRegister, assim:

export default function Input(props) {
  console.log(props.ref);

  let inputClasses = "";

  // * Size
  if (props.size) {
    switch (props.size) {
      case "md":
        inputClasses += " input-md ";
        break;
      case "lg":
        inputClasses += " input-lg ";
        break;
      case "xl":
        inputClasses += " input-xl ";
        break;
    }
  } else {
    inputClasses += " input-base ";
  }

  return (
    <div className="form-control">
      <input
        {...props.inputRegister('email')}
        onBlur={props.onBlur}
        className={inputClasses + props.className}
        onKeyPress={props.onKeyPress}
        onChange={props.onChange}
        type={props.type}
        defaultValue={props.value}
        name={props.name}
        min={props.min}
        max={props.max}
        placeholder={props.placeholder}
        required={props.required}
      />
      {props.subtitle ? <p>{props.subtitle}</p> : ""}
    </div>
  );
}


Não sei se te ajuda ou se foi isso que perguntou, mas espero ter ajudado!

Abraço!

@gustaelesbao
Copy link

gustaelesbao commented Apr 6, 2023

Eu tive esse problema, para resolve isso você precisa dar acesso ao input via ForwardRef, pois o react-hook-form acessa o component via ref, um exemplo do seu caso usando ForwardRef:

export const InputEmail = forwardRef>((props, ref) => { return (
Email address
  <input
      {...register("email")}
      id="email-address"
      name="email"
      type="email"
      autoComplete="email"
      required
      ref={ref}
      className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
      placeholder="Email address"
      {...props}
    />
</div>

);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants