Open1

📝 フォーム系のコンポーネントを作る上で気にしたいことメモ

hanetsukihanetsuki

Bad 😢

type Props<T> = {
  options: { value: T; label?: string }[];
  value: T;
};

export const CustomSelect = <T extends string | number>({ options, ...props }: Props<T>) => {
  const [selected, setSelectedValue] = useState<T>();
  return (
    <select {...props} onChange={(e) => setSelectedValue(e.target.value as T)}>
      {options.map((option) => (
        <option key={option.value} value={option.value} selected={option.value === selected}>
          {option.label ?? option.value}
        </option>
      ))}
    </select>
  );
};
  • propsのvalueが変更されない。
  • Propsに利用したいものを継ぎ足し継ぎ足しで加えなきゃ行けない
    • 特異的な関数名や変数名が生まれてしまう要因

Idea 🤔

type Props<T> = {
  options: ({ value: T; label?: string } & Omit<JSX.IntrinsicElements['option'], 'value' | 'label'>)[];
} & JSX.IntrinsicElements['select'];

export const CustomSelect = <T extends string | number>({ options, ...props }: Props<T>) => {
  return (
    <select {...props}>
      {options.map((option) => (
        <option key={option.value} {...option}>
          {option.label ?? option.value}
        </option>
      ))}
    </select>
  );
};
  • html標準のselectoptionの属性を水準としたPropsの使い方