Dang Kien
Dang Kien

Reputation: 688

Set default value in DatePicker Antd with React-Hook-Form V7

I'm trying to set the default value for Datepicker when fetching data from a server, but it didn't work. Followed the docs in here, I cannot set the defaultValue props because it is only used for first rendering.

I figure out a solution is creating a state and update that state when Datepicker change. But it seems stupid because it re-render each updating. Please let me know a "better solution" or using the "state" of react-hook-form value. Here is my current "stupid solution":

import { DatePicker, Form } from "antd";
import moment, { Moment } from "moment";
import { useEffect, useState } from "react";
import {
  Controller,
  ControllerRenderProps,
  SubmitHandler,
  useForm,
} from "react-hook-form";

const UserList = () => {
  const [date, setDate] = useState<Moment | null>();
  const dateFormat = "YYYY-MM-DD";
  useEffect(() => {
    setDate(() => moment("1963-10-14T00:00:00"));
  }, []);

  const onChange = (date: Moment | null, dateString: string) => {
    console.log(date, dateString);
  };

  interface IForm {
    dob: string;
  }

  const {
    handleSubmit,
    formState: { errors },
    control,
    reset,
    getValues,
    watch,
  } = useForm<IForm>({
    // resolver: yupResolver(UserInfoSchema),
  });

  const dateWatch = watch("dob");

  const handleSubmitForm: SubmitHandler<IForm> = (data: IForm) => {
    console.log(data);
  };

  const onDatePickerChange = (
    date: moment.Moment | null,
    dateString: string,
    props: any
  ) => {
    console.log(dateWatch);
    setDate(date);
    props.field.onChange(dateString);
  };

  return (
    <>
      <Form onFinish={handleSubmit(handleSubmitForm)}>
        <Form.Item label={"label"}>
          <Controller
            control={control}
            name={"dob"}
            render={(props) => (
              <DatePicker
                onChange={(date, dateString) =>
                  onDatePickerChange(date, dateString, props)
                }
                value={date}                    
              />
            )}
          />
        </Form.Item>
      </Form>
    </>
  );
};

export default UserList;

Upvotes: 5

Views: 13468

Answers (1)

Ajeet Shah
Ajeet Shah

Reputation: 19863

You can provide defaultValues to useForm hook for setting default values:

A complete example, see comments:

import { DatePicker, Form } from "antd";
import moment from "moment";
import { Controller, SubmitHandler, useForm } from "react-hook-form";

// We usually define interface/type outside component
interface IForm {
  dob: string;
}

const UserList = () => {
  const { handleSubmit, control } = useForm<IForm>({
    defaultValues: {
      dob: "2021-01-01", // Default value here
    },
  });

  const handleSubmitForm: SubmitHandler<IForm> = (data: IForm) => {};

  return (
    <Form onFinish={handleSubmit(handleSubmitForm)}>
      <Form.Item label="Date of Birth">
        <Controller
          control={control}
          name="dob"
          render={(props) => (
            <DatePicker
              value={moment(props.field.value)} // DatePicker accepts a moment object
              onChange={(_, dateString) => {
                props.field.onChange(dateString); // No need of a state
              }}
            />
          )}
        />
      </Form.Item>
    </Form>
  );
};

Edit:

If you need to set the value after initial render, use reset, example:

useEffect(() => {
  fetchMyData().then(() => {
    reset({
      dob: "2005-05-05", // Set another date
    });
  });
}, []);

Upvotes: 7

Related Questions