react-datepicker
のcustomInput
にref
を適用する方法です。
まずはサンプルを。
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
に指定するコンポーネント
DatePicker
の customInput
に指定するコンポーネントは以下のように定義します。
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
として動作するための値を定義
プロパティにonChange
onClick
value
を定義します。
これらを定義しなければDatePicker
のcustomInput
として正常に動作しません。
③ コンポーネントは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
を定義
useRef
でref
を定義します。
⑧ ref
の使用
イベントハンドラ等でref
を使用します。
⑨ ref
を適用
ref
を適用します。