5

我试图弄清楚如何将 react-hook-form 与 antd 前端一起使用。

我已经制作了这个表单,它似乎可以正常工作(它是多部分表单向导的第 1 部分),只是没有显示错误消息。

谁能看到我在合并这两个表单系统时做错了什么?

我没有收到任何错误,但我想我已经要求两个表单字段都是必需的,但是如果我在未完成它们的情况下按提交,则不会显示错误消息。

import React from "react";
import useForm from "react-hook-form";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { StateMachineProvider, createStore } from "little-state-machine";
import { withRouter } from "react-router-dom";
import { useStateMachine } from "little-state-machine";

import updateAction from "./updateAction";
import { Button, Form, Input,  Divider, Layout, Typography, Skeleton, Switch, Card, Icon, Avatar } from 'antd';


const { Content } = Layout 
const { Text, Paragraph } = Typography;
const { Meta } = Card;

createStore({
  data: {}
});

const General = props => {
  const { register, handleSubmit, errors } = useForm();
  const { action } = useStateMachine(updateAction);
  const onSubit = data => {
    action(data);
    props.history.push("./ProposalMethod");
  };


  return (

      <div>

        <Content
          style={{
            background: '#fff',
            padding: 24,
            margin: "auto",
            minHeight: 280,
            width: '70%'
          }}
        >
        <Form onSubmit={handleSubmit(onSubit)}>

          <h2>Part 1: General</h2>
            <Form.Item label="Title" >
              <Input 
                name="title" 
                placeholder="Add a title" 
                ref={register({ required: true })} 
              />
              {errors.title && 'A title is required.'}
            </Form.Item>
            <Form.Item label="Subtitle" >
              <Input 
                name="subtitle" 
                placeholder="Add a subtitle" 
                ref={register({ required: true })} 
              />
              {errors.subtitle && 'A subtitle is required.'}
            </Form.Item>
            <Form.Item>
              <Button type="secondary" htmlType="submit">
                Next
              </Button>
            </Form.Item>

        </Form>

        </Content>
      </div>  
  );
};

export default withRouter(General);
4

5 回答 5

8

react-hook-form 作者在这里。Antd Input 组件并没有真正暴露 inner ref,所以你必须在 onChangeregister期间useEffect更新值,例如:

const { register, setValue } = useForm();

useEffect(() => {
  register({ name: 'yourField' }, { required: true });
}, [])

<Input name="yourField" onChange={(e) => setValue('yourField', e.target.value)}

我已经构建了一个包装器组件以使 antd 组件集成更容易:https ://github.com/react-hook-form/react-hook-form-input

import React from 'react';
import useForm from 'react-hook-form';
import { RHFInput } from 'react-hook-form-input';
import Select from 'react-select';

const options = [
  { value: 'chocolate', label: 'Chocolate' },
  { value: 'strawberry', label: 'Strawberry' },
  { value: 'vanilla', label: 'Vanilla' },
];

function App() {
  const { handleSubmit, register, setValue, reset } = useForm();

  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <RHFInput
        as={<Select options={options} />}
        rules={{ required: true }}
        name="reactSelect"
        register={register}
        setValue={setValue}
      />
      <button
        type="button"
        onClick={() => {
          reset({
            reactSelect: '',
          });
        }}
      >
        Reset Form
      </button>
      <button>submit</button>
    </form>
  );
}
于 2019-11-12T22:58:30.150 回答
3

这是我的工作方法:

const Example = () => {

 const { control, handleSubmit, errors } = useForm()

  const onSubmit = data => console.log(data)
  console.log(errors)

  return (
    <Form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="email"
        control={control}
        rules={{ required: "Please enter your email address" }}
        as={
          <Form.Item
            label="name"
            validateStatus={errors.email && "error"}
            help={errors.email && errors.email.message}
          >
            <Input />
          </Form.Item>
        }
      />
      <Button htmlType="submit">Submit</Button>
    </Form>
  )
}
于 2020-03-12T21:17:38.743 回答
2

在编写这样的代码时:

<Input
  name="subtitle"
  placeholder="Add a subtitle"
  ref={register({ required: true })}
/>

您假设Input引用绑定到input,但事实并非如此。

实际上,您需要将其绑定到inputRef.input.

您可以使用以下代码检查它:

const App = () => {
  const inputRef = useRef();
  const inputRefHtml = useRef();

  useEffect(() => {
    console.log(inputRef.current);
    console.log(inputRefHtml.current);
  });

  return (
    <FlexBox>
      <Input ref={inputRef} />
      <input ref={inputRefHtml} />
    </FlexBox>
  );
};
# Logs
Input {props: Object, context: Object, refs: Object, updater: Object, saveClearableInput: function ()…}

<input></input>

编辑 Q-58703615-3rdPartyInAnt

请注意,这antd是一个完整的 UI 库(使用 3rd 方“助手”应该“闯红灯”),特别是Form实现了验证器,您可以在 docs 中看到各种示例

于 2019-11-05T06:43:05.940 回答
1

在 Ant Design v4.x + react-hook-form v6.x 中。我们可以正常实现

import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';

import { useIntl } from 'react-intl';
import { Input, Button, Form } from 'antd';

const SignInSchema = yup.object().shape({
  email: yup.string().email().required(),
  password: yup.string().required('required').min(6, 'passwordMin'),
});

interface PropTypes {
  defaultValues?: {
    email: string;
    password: string;
  };
  handleFormSubmit: SubmitHandler<{ email: string; password: string }>;
}

function SignInForm({ defaultValues, handleFormSubmit }: PropTypes) {
  const intl = useIntl();
  const { handleSubmit, control, errors } = useForm({
    defaultValues,
    resolver: yupResolver(SignInSchema),
  });

  return (
    <Form onFinish={handleSubmit(handleFormSubmit)}>
      <Form.Item
        validateStatus={errors && errors['email'] ? 'error' : ''}
        help={errors.email?.message}
      >
        <Controller
          as={Input}
          name="email"
          autoComplete="email"
          control={control}
          placeholder={intl.formatMessage({ id: 'AUTH_INPUT_EMAIL' })}
        />
      </Form.Item>
      <Form.Item
        validateStatus={errors && errors['password'] ? 'error' : ''}
        help={errors.password?.message}
      >
        <Controller
          as={Input}
          name="password"
          type="password"
          control={control}
          autoComplete="new-password"
          defaultValue=""
          placeholder={intl.formatMessage({ id: 'AUTH_INPUT_PASSWORD' })}
        />
      </Form.Item>

      <Button type="primary" htmlType="submit">
        {intl.formatMessage({ id: 'SIGN_IN_SUBMIT_BUTTON' })}
      </Button>
    </Form>
  );
}

export default SignInForm;

于 2021-02-12T04:36:14.633 回答
0

如果有人仍然对接近 Ant 提供的表单输入的默认样式感兴趣,下面是我如何让它工作的:

import { Form, Button, Input } from 'antd';
import { useForm, Controller } from 'react-hook-form';

function MyForm() {
    const { control, handleSubmit, errors, setValue } = useForm();
    const emailError = errors.email && 'Enter your email address';

    const onSubmit = data => { console.log(data) };

    const EmailInput = (
        <Form.Item>
            <Input
                type="email"
                placeholder="Email"
                onChange={e => setValue('email', e.target.value, true)}
                onBlur={e => setValue('email', e.target.value, true)}
            />
        </Form.Item>
    );


    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <Controller 
                as={EmailInput} 
                name="email" 
                control={control} 
                defaultValue=""
                rules={{
                    required: true
                }}
                validateStatus={emailError ? 'error' : ''}
                help={emailError}
            />

            <Button block type="primary" htmlType="submit">
                Submit
            </Button>
        </form>
    );
}

代码沙盒示例

于 2020-02-10T21:15:49.010 回答