Reactjs 使用react钩子表单引用问题

Reactjs 使用react钩子表单引用问题,reactjs,react-hooks,react-props,react-hook-form,Reactjs,React Hooks,React Props,React Hook Form,我正在尝试在当前项目中使用react hook form创建表单验证。我已经尝试过不同的方法,但总是因为ref属性而出错。如果我将更改为输入,它将开始工作。 你知道怎么解决这个问题吗 联系方式 import React from 'react'; import { useForm } from "react-hook-form"; import FormField from '../../components/FormField'; import Button from '.

我正在尝试在当前项目中使用
react hook form
创建表单验证。我已经尝试过不同的方法,但总是因为
ref
属性而出错。如果我将
更改为
输入
,它将开始工作。 你知道怎么解决这个问题吗

联系方式

import React from 'react';
import { useForm } from "react-hook-form";
import FormField from '../../components/FormField';
import Button from '../../components/Button';

const Contact = () => {
    const { handleSubmit, register, errors } = useForm();
    const onSubmit = values => console.log(values);

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <FormField
                name="email"
                onChange={() => { console.log("changed!") }}
                ref={register({
                    required: "Required",
                    pattern: {
                        value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
                        message: "invalid email address"
                    }
                })}
            />
            <p style={{ color: "red" }}>
                {errors.email && errors.email.message}
            </p>


            <Button>Submit</Button>
        </form>
    );
};

export default Contact;
从“React”导入React;
从“react hook form”导入{useForm};
从“../../components/FormField”导入FormField;
从“../../components/Button”导入按钮;
常量联系人=()=>{
const{handleSubmit,register,errors}=useForm();
const onSubmit=values=>console.log(值);
返回(
{console.log(“已更改!”)}
ref={寄存器({
必选:“必选”,
模式:{
值:/^[A-Z0-9.\%+-]+@[A-Z0-9.-]+\[A-Z]{2,}$/i,
消息:“无效的电子邮件地址”
}
})}
/>

{errors.email&&errors.email.message}

提交 ); }; 导出默认联系人;
FormField

import React from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";


const FormFieldWrapper = styled.div`
  position: relative;
  textarea {
    min-height: 150px;
  }
  input[type="color"] {
    padding-left: 67px;
  }
`;

const Label = styled.label``;

Label.Text = styled.span`
  color: #e5e5e5;
  height: 57px;
  position: absolute;
  top: 0;
  left: 16px;

  display: flex;
  align-items: center;

  transform-origin: 0% 0%;
  font-size: 18px;
  font-style: normal;
  font-weight: 300;

  transition: 0.1s ease-in-out;
`;

const Input = styled.input`
  background: #53585d;
  color: #f5f5f5;
  display: block;
  width: 100%;
  height: 57px;
  font-size: 18px;

  outline: 0;
  border: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid #53585d;

  padding: 16px 16px;
  margin-bottom: 45px;

  resize: none;
  border-radius: 4px;
  transition: border-color 0.3s;

  &:focus {
    border-bottom-color: var(--primary);
  }
  &:focus:not([type="color"]) + ${Label.Text} {
    transform: scale(0.6) translateY(-10px);
  }
  ${({ value }) => {
    const hasValue = value.length > 0;
    return (
      hasValue &&
      css`
        &:not([type="color"]) + ${Label.Text} {
          transform: scale(0.6) translateY(-10px);
        }
      `
    );
  }}
`;

function FormField({ label, type, name, value, onChange, ref }) {
  const isTypeTextArea = type === "textarea";
  const tag = isTypeTextArea ? "textarea" : "input";
  return (
    <FormFieldWrapper>
      <Label>
        <Input
          as={tag}
          type={type}
          value={value}
          name={name}
          onChange={onChange}
          ref={ref}
        />
        <Label.Text>{label}:</Label.Text>
      </Label>
    </FormFieldWrapper>
  );
}

FormField.defaultProps = {
  type: "text",
  value: "",
};

FormField.propTypes = {
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  type: PropTypes.string,
  value: PropTypes.string,
  onChange: PropTypes.func,
  ref: PropTypes.func
};

export default FormField;
从“React”导入React;
从“道具类型”导入道具类型;
导入样式化,{css}来自“样式化组件”;
const FormFieldWrapper=styled.div`
位置:相对位置;
文本区{
最小高度:150px;
}
输入[type=“color”]{
左侧填充:67px;
}
`;
const Label=styled.Label`;
Label.Text=styled.span`
颜色:#E5;
高度:57px;
位置:绝对位置;
排名:0;
左:16px;
显示器:flex;
对齐项目:居中;
变换原点:0%0%;
字号:18px;
字体风格:普通;
字体大小:300;
转换:0.1s易入易出;
`;
常量输入=styled.Input`
背景#53585d;
颜色:#F5;
显示:块;
宽度:100%;
高度:57px;
字号:18px;
大纲:0;
边界:0;
边框顶部:4倍实心透明;
边框底部:4px实心#53585d;
填充:16px 16px;
边缘底部:45像素;
调整大小:无;
边界半径:4px;
过渡:边框颜色0.3s;
&:焦点{
边框底色:var(--主色);
}
&:focus:not([type=“color”])+${Label.Text}{
变换:比例(0.6)translateY(-10px);
}
${({value})=>{
常量hasValue=value.length>0;
返回(
hasValue&&
css`
&:not([type=“color”])+${Label.Text}{
变换:比例(0.6)translateY(-10px);
}
`
);
}}
`;
函数FormField({label,type,name,value,onChange,ref}){
常量isTypeTextArea=type==“textarea”;
const tag=isTypeTextArea?“textarea”:“输入”;
返回(
{label}:
);
}
FormField.defaultProps={
键入:“文本”,
值:“”,
};
FormField.propTypes={
标签:PropTypes.string,
名称:PropTypes.string.isRequired,
类型:PropTypes.string,
值:PropTypes.string,
onChange:PropTypes.func,
ref:PropTypes.func
};
导出默认表单字段;
错误:

引用寄存器时,应按如下方式使用,这样我们就不会出现引用问题,寄存器将更改输入中的值,因此我们不需要传递值属性:

联系人:

import React from "react";
import { useForm } from "react-hook-form";
import FormField from "../../components/FormField";
import Button from "../../components/Button";

const Contact = () => {
  const { handleSubmit, register, errors } = useForm();
  const onSubmit = (values) => console.log("values", values);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <FormField
        name="email"
        onChange={() => {
          console.log("changed!");
        }}
        register={register}
      />
      <p style={{ color: "red" }}>{errors.email && errors.email.message}</p>

      <Button>Submit</Button>
    </form>
  );
};

export default Contact;
从“React”导入React;
从“react hook form”导入{useForm};
从“../../components/FormField”导入FormField;
从“../../components/Button”导入按钮;
常量联系人=()=>{
const{handleSubmit,register,errors}=useForm();
const onSubmit=(values)=>console.log(“values”,values);
返回(
{
log(“已更改!”);
}}
寄存器={register}
/>

{errors.email&&errors.email.message}

提交 ); }; 导出默认联系人;
FormField:

import React from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";

const FormFieldWrapper = styled.div`
  position: relative;
  textarea {
    min-height: 150px;
  }
  input[type="color"] {
    padding-left: 67px;
  }
`;

const Label = styled.label``;

Label.Text = styled.span`
  color: #e5e5e5;
  height: 57px;
  position: absolute;
  top: 0;
  left: 16px;

  display: flex;
  align-items: center;

  transform-origin: 0% 0%;
  font-size: 18px;
  font-style: normal;
  font-weight: 300;

  transition: 0.1s ease-in-out;
`;

const Input = styled.input`
  background: #53585d;
  color: #f5f5f5;
  display: block;
  width: 100%;
  height: 57px;
  font-size: 18px;

  outline: 0;
  border: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid #53585d;

  padding: 16px 16px;
  margin-bottom: 45px;

  resize: none;
  border-radius: 4px;
  transition: border-color 0.3s;

  &:focus {
    border-bottom-color: var(--primary);
  }
  &:focus:not([type="color"]) + ${Label.Text} {
    transform: scale(0.6) translateY(-10px);
  }
  ${({ value = {} }) => { // here you should find an other approch because there is no value props
    const hasValue = value.length > 0;
    return (
      hasValue &&
      css`
        &:not([type="color"]) + ${Label.Text} {
          transform: scale(0.6) translateY(-10px);
        }
      `
    );
  }}
`;

const FormField = ({ label, type, name, onChange, register }) => {
  const isTypeTextArea = type === "textarea";
  const tag = isTypeTextArea ? "textarea" : "input";
  return (
    <FormFieldWrapper>
      <Label>
        <Input
          as={tag}
          type={type}
          //   value={value} it's not a controlled input! so the register'ill provide the value
          name={name}
          onChange={onChange}
          ref={register({
            required: "Required",
            pattern: {
              value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
              message: "invalid email address",
            },
          })}
        />
        <Label.Text>{label}:</Label.Text>
      </Label>
    </FormFieldWrapper>
  );
};

FormField.defaultProps = {
  type: "text",
  value: "",
};

FormField.propTypes = {
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  type: PropTypes.string,
  value: PropTypes.string,
  onChange: PropTypes.func,
  ref: PropTypes.func,
};

export default FormField;
从“React”导入React;
从“道具类型”导入道具类型;
导入样式化,{css}来自“样式化组件”;
const FormFieldWrapper=styled.div`
位置:相对位置;
文本区{
最小高度:150px;
}
输入[type=“color”]{
左侧填充:67px;
}
`;
const Label=styled.Label`;
Label.Text=styled.span`
颜色:#E5;
高度:57px;
位置:绝对位置;
排名:0;
左:16px;
显示器:flex;
对齐项目:居中;
变换原点:0%0%;
字号:18px;
字体风格:普通;
字体大小:300;
转换:0.1s易入易出;
`;
常量输入=styled.Input`
背景#53585d;
颜色:#F5;
显示:块;
宽度:100%;
高度:57px;
字号:18px;
大纲:0;
边界:0;
边框顶部:4倍实心透明;
边框底部:4px实心#53585d;
填充:16px 16px;
边缘底部:45像素;
调整大小:无;
边界半径:4px;
过渡:边框颜色0.3s;
&:焦点{
边框底色:var(--主色);
}
&:focus:not([type=“color”])+${Label.Text}{
变换:比例(0.6)translateY(-10px);
}
${({value={}}})=>{//这里您应该找到另一种方法,因为没有值道具
常量hasValue=value.length>0;
返回(
hasValue&&
css`
&:not([type=“color”])+${Label.Text}{
变换:比例(0.6)translateY(-10px);
}
`
);
}}
`;
const FormField=({label,type,name,onChange,register})=>{
常量isTypeTextArea=type==“textarea”;
const tag=isTypeTextArea?“textarea”:“输入”;
返回(
{label}:
);
};
FormField.defaultProps={
键入:“文本”,
值:“”,
};
FormField.propTypes={
标签:PropTypes.string,
名称:PropTypes.string.isRequired,
类型:PropTypes.string,
值:PropTypes.string,
onChange:PropTypes.func,
参考:PropTypes.func,
};
导出默认表单字段;
引用寄存器时应按如下方式使用,这样我们就不会出现引用问题,寄存器将更改输入中的值,因此我们不需要