Pan*_*ood 3 reactjs react-props react-hooks react-hook-form
react-hook-form
我正在尝试在当前项目中创建表单验证。我已经尝试过不同的方法,但总是因为属性而出错ref
。如果我将 更改<FormField>
为input
,它就会开始工作。知道如何解决这个问题吗?
接触
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;
Run Code Online (Sandbox Code Playgroud)
表单域
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;
Run Code Online (Sandbox Code Playgroud)
参考文档,寄存器应按如下方式使用,这样我们就不会遇到引用问题,并且寄存器将更改输入内的值,因此我们不需要传递 value prop:
接触 :
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;
Run Code Online (Sandbox Code Playgroud)
表单字段:
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;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13292 次 |
最近记录: |