Register 作为 prop 传递时不是一个函数?

问题描述 投票:0回答:3

我第一次使用react-hook-form。我正在阅读文档并遵循。同样,我已经布置了组件并设计了它们的样式。现在我试图在表单提交后提醒数据。

这是

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.

希望你能为我的困惑带来光明。

亲切的问候 库库

forms validation next.js styled-components react-hook-form
3个回答
5
投票

最简单的解决方案是利用 React hook 表单的上下文并使用 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 });
};

1
投票

useFormContext
是一个很好的解决方案,由 @Sean W

解释

这是另一种没有

useFormContext
的解决方案,您可以照常使用
register
而不是将其作为 prop 传递。您只需转发 TextInput 的引用即可。

👉🏻您可以在这里找到一个实例:https://stackoverflow.com/a/68667226/4973076


0
投票

我可以用这种方式修复它:

我像这样将寄存器作为道具传递:

`<TextField

标签={“电子邮件”} 姓名={“电子邮件”} 必需的 注册={{...注册(“电子邮件”, 选项)}} 错误={错误} />`

我在组件内部使用了它,如下所示:

`<input    {...register}    type="text"    name={name}    id={id}    />`
© www.soinside.com 2019 - 2024. All rights reserved.