Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-hook-form reset is not working with Controller + antd

I'm trying to use react-hook-form together with the antd <Input /> component

I'm not getting reset to work with <Controller />

Here is my code:

const  NormalLoginForm = () =>{
  const {reset, handleSubmit, control} = useForm();

  const onSubmit = handleSubmit(async ({username, password}) => {
        console.log(username, password);
        reset();
  });

    return (
      <form onSubmit={onSubmit} className="login-form">
        <Form.Item>
                        <Controller as={<Input
                            prefix={<Icon type="user" style={{color: 'rgba(0,0,0,.25)'}}/>}
                            autoFocus={true}
                            placeholder="Benutzername"

                        />} name={'username'} control={control}/>

                    </Form.Item>
                    <Form.Item>
                        <Controller as={<Input
                            prefix={<Icon type="lock" style={{color: 'rgba(0,0,0,.25)'}}/>}
                            type="password"
                            placeholder="Passwort"

                        />} name={'password'} control={control}/>
                    </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit" className="login-form-button">
            Log in
          </Button>
        </Form.Item>
      </form>
    );
}

I'm expecting that the two input fields are getting cleared when the form is submitted. But that doesn't work.

Am I missing something here?

Example on Stackblitz https://stackblitz.com/edit/react-y94jpf?file=index.js

Edit:

The RHFInput mentioned here React Hook Form with AntD Styling is now part of react-hook-form and has been renamed to Controller. I'm already using it.

I've figured out that chaning

reset();

to

reset({
  username:'',
  password:''
});

solves the problem.

However - I wanted to reset the whole form without explicitly assigning new values.

Edit 2:

Bill has pointed out in the comments that it's almost impossible to detect the default values for external controlled inputs. Therefore we're forced to pass the default values to the reset method. That makes totally sense to me.

like image 551
emcell Avatar asked Jan 23 '20 09:01

emcell


1 Answers

You must wrapper the components for antd and create a render component, it is very similar if you use Material UI, So the code can be like:

import { Input, Button } from 'antd';
import React from 'react';
import 'antd/dist/antd.css';
import {useForm, Controller} from 'react-hook-form';

const RenderInput = ({
  field: {
    onChange,
    value
  },
  prefix,
  autoFocus,
  placeholder
}) => {

  return (
    <Input
      prefix={prefix}
      autoFocus={autoFocus}
      placeholder={placeholder}
      onChange={onChange}
      value={value}
    />
  );
}

export const  NormalLoginForm = () =>{
  const {reset, handleSubmit, control} = useForm();

  const onSubmit = ({username, password}) => {
        console.log(username, password);
        reset();
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="login-form">
      <Controller
        control={control}
        name={'username'}
        defaultValue=""
        render={ ({field}) => (
          <RenderInput
            field={field}
            autoFocus={true}
            placeholder="Benutzername"
          />
          )}
      />
      <Controller
        render={ ({field}) => (
          <RenderInput
            field={field}
            type="password"
            placeholder="Passwort"
          />
          )}
        defaultValue=""      
        name={'password'}
        control={control}
      />
      <Button
        type="primary"
        htmlType="submit"
        className="login-form-button"
      >
        Log in
      </Button>
    </form>
  );
}

export default NormalLoginForm;

You can notice that I did't put the Icon ,it was because I tested using the version 4 for antd and something change in how to use the icons.

like image 138
andres.ara Avatar answered Sep 22 '22 11:09

andres.ara