LoginSignup
3
3

More than 3 years have passed since last update.

React DatePickerのcustomInputにrefを適用する

Posted at

react-datepickercustomInputrefを適用する方法です。
まずはサンプルを。

import React from "react";
import DatePicker from "react-datepicker";

interface InputProps {
  inputRef: React.Ref<HTMLInputElement>;
  onClick?: React.MouseEventHandler<HTMLInputElement>;
  onChange?: React.ChangeEventHandler<HTMLInputElement>;
  value?: string | ReadonlyArray<string> | number;
}

const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
  return <input
    type="text"
    ref={props.inputRef}
    onClick={props.onClick}
    onChange={props.onChange}
    value={props.value}
  />;
})

interface Props {
  inputRef: React.Ref<HTMLInputElement>;
}

const DP: React.FC<Props> = props => {
  const [selected, setSelected] = React.useState<Date | null>(null);
  const onChangeDatePicker = (date: Date | [Date, Date] | null) => {
    if (date && date instanceof Date) {
      setSelected(date);
    }
  };
  return (
    <DatePicker
      selected={selected}
      onChange={onChangeDatePicker}
      customInput={
        <Input inputRef={props.inputRef} />
      } />
  );
};

const App: React.FC = () => {
  const ref = React.useRef<HTMLInputElement>(null);
  const onClick: React.MouseEventHandler<HTMLButtonElement> = event => {
    console.log(ref.current?.value);
  };
  return (
    <form>
      <DP inputRef={ref} /><br/>
      <button type="submit" onClick={onClick}>送信</button>
    </form>
  );
};

順番に説明していきます。

customInputに指定するコンポーネント

DatePickercustomInput に指定するコンポーネントは以下のように定義します。

interface InputProps {
  inputRef: React.Ref<HTMLInputElement>; // ①
  onClick?: React.MouseEventHandler<HTMLInputElement>; // ②
  onChange?: React.ChangeEventHandler<HTMLInputElement>; // ②
  value?: string | ReadonlyArray<string> | number; // ②
}

const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => { // ③
  return <input
    type="text"
    ref={props.inputRef} // ④
    onClick={props.onClick}
    onChange={props.onChange}
    value={props.value}
  />;
})

① プロパティにReact.Ref型の値を定義

プロパティにReact.Ref型の値を定義します。
名称はref以外にする必要があります。

② プロパティにcustomInputとして動作するための値を定義

プロパティにonChangeonClickvalueを定義します。
これらを定義しなければDatePickercustomInputとして正常に動作しません。

③ コンポーネントはforwardRefで定義

refを親子間で受け渡せるようforwardRefでコンポーネントを定義します。
ただし引数refは使用しません。

refを適用したいコンポーネントにプロパティを指定

refを適用したいコンポーネントにforwardRefの引数ではなくプロパティのReact.Ref型の値を指定します。

DatePickerの定義

customInputに指定するコンポーネントを定義したら、これを使用してDatePickerを定義します。

interface Props {
  inputRef: React.Ref<HTMLInputElement>; // ⑤
}

const DP: React.FC<Props> = props => {
  const [selected, setSelected] = React.useState<Date | null>(null);
  const onChangeDatePicker = (date: Date | [Date, Date] | null) => {
    if (date && date instanceof Date) {
      setSelected(date);
    }
  };
  return (
    <DatePicker
      selected={selected}
      onChange={onChangeDatePicker}
      customInput={
        <Input inputRef={props.inputRef} /> // ⑥
      } />
  );
};

⑤ プロパティにReact.Ref型の値を定義

プロパティにReact.Ref型の値を定義します。
名称はref以外にしたほうが無難です。

customInputのコンポーネントにプロパティを指定

customInputのコンポーネントにプロパティのReact.Ref型の値を指定します。

useRefの定義

const App: React.FC = () => {
  const ref = React.useRef<HTMLInputElement>(null); // ⑦
  const onClick: React.MouseEventHandler<HTMLButtonElement> = event => {
    console.log(ref.current?.value); // ⑧
  };
  return (
    <form>
      <DP inputRef={ref} /><br/> // ⑨
      <button type="submit" onClick={onClick}>送信</button>
    </form>
  );
};

refを定義

useRefrefを定義します。

refの使用

イベントハンドラ等でrefを使用します。

refを適用

refを適用します。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3