{"id":3487,"date":"2026-10-13T08:57:44","date_gmt":"2026-10-12T23:57:44","guid":{"rendered":"https:\/\/qol-kk.com\/wp2\/?p=3487"},"modified":"2026-10-13T08:57:44","modified_gmt":"2026-10-12T23:57:44","slug":"20260930-plan045","status":"publish","type":"post","link":"https:\/\/qol-kk.com\/wp2\/blog\/2026\/10\/13\/20260930-plan045\/","title":{"rendered":"React \u3067\u30d5\u30a9\u30fc\u30e0\u7ba1\u7406\u5165\u9580\uff1aReact Hook Form \u3067\u697d\u306b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u307e\u3067\u4f5c\u308b"},"content":{"rendered":"<h2>\u6982\u8981<\/h2>\n<p>React \u3067\u30d5\u30a9\u30fc\u30e0\u3092\u4f5c\u308b\u3068\u3001<code>useState<\/code> \u3092\u5165\u529b\u6b04\u306e\u6570\u3060\u3051\u4e26\u3079\u3001<code>onChange<\/code> \u3092\u66f8\u304d\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u624b\u3067\u7d44\u307f\u3001\u30a8\u30e9\u30fc\u8868\u793a\u306e\u72b6\u614b\u3082\u5225\u9014\u7ba1\u7406\u3057\u2026\u2026\u3068\u3001\u3042\u3063\u3068\u3044\u3046\u9593\u306b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304c\u80a5\u5927\u5316\u3057\u307e\u3059\u3002React Hook Form\uff08\u4ee5\u4e0b RHF\uff09\u306f\u3001\u3053\u306e\u5b9a\u578b\u4f5c\u696d\u3092\u5927\u5e45\u306b\u6e1b\u3089\u3057\u3001\u3057\u304b\u3082\u300c\u5165\u529b\u306e\u305f\u3073\u306b\u5168\u4f53\u304c\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3055\u308c\u308b\u300d\u554f\u984c\u3082\u6291\u3048\u3066\u304f\u308c\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002<\/p>\n<p>\u3053\u306e\u8a18\u4e8b\u3067\u306f\u3001\u7d20\u306e <code>useState<\/code> \u3067\u4f5c\u3063\u305f\u30d5\u30a9\u30fc\u30e0\u3092\u51fa\u767a\u70b9\u306b\u3001RHF \u3078\u7f6e\u304d\u63db\u3048\u3001\u6700\u7d42\u7684\u306b Zod \u3067\u30b9\u30ad\u30fc\u30de\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u307e\u3067\u901a\u3059\u3068\u3053\u308d\u3092\u30cf\u30f3\u30ba\u30aa\u30f3\u3067\u9032\u3081\u307e\u3059\u3002<\/p>\n<h2>\u74b0\u5883<\/h2>\n<ul>\n<li>Node.js 20 \u7cfb<\/li>\n<li>React 18 \/ TypeScript 5<\/li>\n<li>Vite\uff08react-ts \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\uff09<\/li>\n<li>react-hook-form 7 \u7cfb \/ zod 3 \u7cfb \/ @hookform\/resolvers 3 \u7cfb<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">npm install react-hook-form zod @hookform\/resolvers<\/pre>\n<h2>\u7d20\u306e useState \u3060\u3068\u4f55\u304c\u3064\u3089\u3044\u304b<\/h2>\n<pre class=\"lang:default decode:true\">import { useState } from \"react\";\n\nexport function SignUpFormNaive() {\n  const [email, setEmail] = useState(\"\");\n  const [password, setPassword] = useState(\"\");\n  const [errors, setErrors] = useState&lt;{ email?: string; password?: string }&gt;({});\n\n  const handleSubmit = (e: React.FormEvent) =&gt; {\n    e.preventDefault();\n    const next: typeof errors = {};\n    if (!email.includes(\"@\")) next.email = \"\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u304c\u4e0d\u6b63\u3067\u3059\";\n    if (password.length &lt; 8) next.password = \"8\u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\";\n    setErrors(next);\n    if (Object.keys(next).length &gt; 0) return;\n    console.log({ email, password });\n  };\n\n  return (\n    &lt;form onSubmit={handleSubmit}&gt;\n      &lt;input value={email} onChange={(e) =&gt; setEmail(e.target.value)} \/&gt;\n      {errors.email &amp;&amp; &lt;p&gt;{errors.email}&lt;\/p&gt;}\n      &lt;input\n        type=\"password\"\n        value={password}\n        onChange={(e) =&gt; setPassword(e.target.value)}\n      \/&gt;\n      {errors.password &amp;&amp; &lt;p&gt;{errors.password}&lt;\/p&gt;}\n      &lt;button type=\"submit\"&gt;\u767b\u9332&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}<\/pre>\n<p>\u554f\u984c\u70b9\u306f\u4e3b\u306b3\u3064\u3067\u3059\u3002<\/p>\n<ol>\n<li>\u5165\u529b\u6b04\u304c\u5897\u3048\u308b\u307b\u3069 <code>useState<\/code> \u3068 <code>onChange<\/code> \u304c\u5897\u6b96\u3059\u308b<\/li>\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u30eb\u30fc\u30eb\u304c\u30ed\u30b8\u30c3\u30af\u306b\u57cb\u3082\u308c\u3001\u518d\u5229\u7528\u3057\u3065\u3089\u3044<\/li>\n<li>1\u6587\u5b57\u6253\u3064\u305f\u3073\u306b <code>setState<\/code> \u304c\u8d70\u308a\u3001\u30d5\u30a9\u30fc\u30e0\u5168\u4f53\u304c\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3055\u308c\u308b<\/li>\n<\/ol>\n<h2>RHF \u3078\u7f6e\u304d\u63db\u3048\u308b<\/h2>\n<p>RHF \u306e\u4e2d\u5fc3\u306f <code>useForm<\/code> \u30d5\u30c3\u30af\u3068\u3001\u305d\u308c\u304c\u8fd4\u3059 <code>register<\/code> \u3067\u3059\u3002<code>register<\/code> \u3092 input \u306b\u5c55\u958b\u3059\u308b\u3060\u3051\u3067\u3001\u5024\u306e\u8ffd\u8de1\u30fbonChange\u30fbonBlur \u306e\u914d\u7dda\u304c\u6e08\u307f\u307e\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">import { useForm } from \"react-hook-form\";\n\ntype FormValues = {\n  email: string;\n  password: string;\n};\n\nexport function SignUpForm() {\n  const {\n    register,\n    handleSubmit,\n    formState: { errors, isSubmitting },\n  } = useForm&lt;FormValues&gt;();\n\n  const onSubmit = (data: FormValues) =&gt; {\n    console.log(data);\n  };\n\n  return (\n    &lt;form onSubmit={handleSubmit(onSubmit)}&gt;\n      &lt;input\n        {...register(\"email\", {\n          required: \"\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u5fc5\u9808\u3067\u3059\",\n          pattern: {\n            value: \/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$\/,\n            message: \"\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u304c\u4e0d\u6b63\u3067\u3059\",\n          },\n        })}\n      \/&gt;\n      {errors.email &amp;&amp; &lt;p&gt;{errors.email.message}&lt;\/p&gt;}\n\n      &lt;input\n        type=\"password\"\n        {...register(\"password\", {\n          required: \"\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5fc5\u9808\u3067\u3059\",\n          minLength: { value: 8, message: \"8\u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\" },\n        })}\n      \/&gt;\n      {errors.password &amp;&amp; &lt;p&gt;{errors.password.message}&lt;\/p&gt;}\n\n      &lt;button type=\"submit\" disabled={isSubmitting}&gt;\n        \u767b\u9332\n      &lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}<\/pre>\n<p>\u30dd\u30a4\u30f3\u30c8\u3092\u6574\u7406\u3057\u307e\u3059\u3002<\/p>\n<ul>\n<li><code>useForm&lt;FormValues&gt;()<\/code> \u306b\u578b\u3092\u6e21\u3059\u3068\u3001<code>register<\/code> \u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u540d\u3084 <code>onSubmit<\/code> \u306e\u5f15\u6570\u304c\u578b\u30c1\u30a7\u30c3\u30af\u3055\u308c\u308b<\/li>\n<li><code>handleSubmit<\/code> \u306f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u901a\u904e\u3057\u305f\u3068\u304d\u3060\u3051 <code>onSubmit<\/code> \u3092\u547c\u3076<\/li>\n<li><code>formState.errors<\/code> \u306b\u30d5\u30a3\u30fc\u30eb\u30c9\u540d\u3054\u3068\u306e\u30a8\u30e9\u30fc\u304c\u5165\u308b<\/li>\n<li><code>isSubmitting<\/code> \u3092\u4f7f\u3048\u3070\u4e8c\u91cd\u9001\u4fe1\u9632\u6b62\u306e\u30dc\u30bf\u30f3\u7121\u52b9\u5316\u304c\u7c21\u5358\u306b\u66f8\u3051\u308b<\/li>\n<\/ul>\n<p><code>useState<\/code> \u30921\u3064\u3082\u66f8\u3044\u3066\u3044\u306a\u3044\u70b9\u306b\u6ce8\u76ee\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u5024\u306e\u4fdd\u6301\u306f RHF \u304c\u5185\u90e8\u3067\u6301\u3061\u307e\u3059\u3002<\/p>\n<h2>\u306a\u305c\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u304c\u6e1b\u308b\u306e\u304b<\/h2>\n<p>RHF \u306f\u65e2\u5b9a\u3067 <strong>\u975e\u5236\u5fa1\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\uff08uncontrolled\uff09<\/strong> \u3068\u3057\u3066\u52d5\u304d\u307e\u3059\u3002<code>register<\/code> \u306f\u5185\u90e8\u3067 <code>ref<\/code> \u3092\u4f7f\u3063\u3066 DOM \u304b\u3089\u5024\u3092\u8aad\u3080\u305f\u3081\u30011\u6587\u5b57\u6253\u3064\u305f\u3073\u306b React \u306e state \u304c\u66f4\u65b0\u3055\u308c\u308b\u308f\u3051\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u7d50\u679c\u3068\u3057\u3066\u3001\u5165\u529b\u4e2d\u306b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30c4\u30ea\u30fc\u304c\u518d\u63cf\u753b\u3055\u308c\u7d9a\u3051\u308b\u3053\u3068\u3092\u907f\u3051\u3089\u308c\u307e\u3059\u3002<\/p>\n<p>\u5165\u529b\u4e2d\u306e\u5024\u3092\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u306b\u753b\u9762\u3078\u53cd\u6620\u3057\u305f\u3044\u3068\u304d\u306f <code>watch<\/code> \u3092\u4f7f\u3044\u307e\u3059\u3002\u305f\u3060\u3057 <code>watch<\/code> \u3057\u305f\u7b87\u6240\u306f\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u306e\u5bfe\u8c61\u306b\u306a\u308b\u306e\u3067\u3001\u5fc5\u8981\u306a\u7bc4\u56f2\u306b\u9650\u5b9a\u3059\u308b\u306e\u304c\u30b3\u30c4\u3067\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">const email = watch(\"email\");<\/pre>\n<h2>Zod \u3067\u30b9\u30ad\u30fc\u30de\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u3059\u308b<\/h2>\n<p>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30921\u304b\u6240\u306e\u30b9\u30ad\u30fc\u30de\u306b\u96c6\u7d04\u3057\u3001\u305d\u3053\u304b\u3089\u578b\u3082\u5c0e\u51fa\u3067\u304d\u308b\u306e\u304c Zod \u3068\u306e\u7d44\u307f\u5408\u308f\u305b\u3067\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">import { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform\/resolvers\/zod\";\nimport { z } from \"zod\";\n\nconst schema = z\n  .object({\n    email: z.string().email(\"\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u304c\u4e0d\u6b63\u3067\u3059\"),\n    password: z.string().min(8, \"8\u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\"),\n    passwordConfirm: z.string(),\n  })\n  .refine((v) =&gt; v.password === v.passwordConfirm, {\n    message: \"\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\",\n    path: [\"passwordConfirm\"],\n  });\n\ntype FormValues = z.infer&lt;typeof schema&gt;;\n\nexport function SignUpFormWithZod() {\n  const {\n    register,\n    handleSubmit,\n    formState: { errors },\n  } = useForm&lt;FormValues&gt;({\n    resolver: zodResolver(schema),\n  });\n\n  const onSubmit = (data: FormValues) =&gt; {\n    console.log(data);\n  };\n\n  return (\n    &lt;form onSubmit={handleSubmit(onSubmit)}&gt;\n      &lt;input {...register(\"email\")} \/&gt;\n      {errors.email &amp;&amp; &lt;p&gt;{errors.email.message}&lt;\/p&gt;}\n\n      &lt;input type=\"password\" {...register(\"password\")} \/&gt;\n      {errors.password &amp;&amp; &lt;p&gt;{errors.password.message}&lt;\/p&gt;}\n\n      &lt;input type=\"password\" {...register(\"passwordConfirm\")} \/&gt;\n      {errors.passwordConfirm &amp;&amp; &lt;p&gt;{errors.passwordConfirm.message}&lt;\/p&gt;}\n\n      &lt;button type=\"submit\"&gt;\u767b\u9332&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}<\/pre>\n<p>\u5b09\u3057\u3044\u70b9\u306f2\u3064\u3067\u3059\u3002<\/p>\n<ul>\n<li><code>z.infer&lt;typeof schema&gt;<\/code> \u3067\u30b9\u30ad\u30fc\u30de\u304b\u3089\u578b\u3092\u81ea\u52d5\u751f\u6210\u3067\u304d\u308b\u306e\u3067\u3001\u578b\u5b9a\u7fa9\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u304c\u4e8c\u91cd\u7ba1\u7406\u306b\u306a\u3089\u306a\u3044<\/li>\n<li><code>.refine<\/code> \u3067\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u307e\u305f\u3044\u3060\u691c\u8a3c\uff08\u30d1\u30b9\u30ef\u30fc\u30c9\u4e00\u81f4\u306a\u3069\uff09\u3092\u5ba3\u8a00\u7684\u306b\u66f8\u3051\u308b<\/li>\n<\/ul>\n<h2>UI \u30e9\u30a4\u30d6\u30e9\u30ea\u306a\u3069\u300c\u5236\u5fa1\u3055\u308c\u305f\u5165\u529b\u300d\u3068\u306e\u9023\u643a<\/h2>\n<p><code>value<\/code>\/<code>onChange<\/code> \u3092\u6e21\u3059\u524d\u63d0\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\uff08Material UI \u3084 React Select \u306a\u3069\uff09\u306f <code>register<\/code> \u3092\u305d\u306e\u307e\u307e\u5c55\u958b\u3067\u304d\u307e\u305b\u3093\u3002\u3053\u306e\u5834\u5408\u306f <code>Controller<\/code> \u3092\u4f7f\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true\">import { Controller, useForm } from \"react-hook-form\";\nimport Select from \"react-select\";\n\nconst options = [\n  { value: \"jp\", label: \"\u65e5\u672c\" },\n  { value: \"us\", label: \"\u30a2\u30e1\u30ea\u30ab\" },\n];\n\nfunction CountryField() {\n  const { control, handleSubmit } = useForm&lt;{ country: string }&gt;();\n\n  return (\n    &lt;form onSubmit={handleSubmit((d) =&gt; console.log(d))}&gt;\n      &lt;Controller\n        name=\"country\"\n        control={control}\n        rules={{ required: \"\u56fd\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\" }}\n        render={({ field }) =&gt; (\n          &lt;Select\n            options={options}\n            value={options.find((o) =&gt; o.value === field.value)}\n            onChange={(opt) =&gt; field.onChange(opt?.value)}\n          \/&gt;\n        )}\n      \/&gt;\n      &lt;button type=\"submit\"&gt;\u9001\u4fe1&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}<\/pre>\n<h2>\u78ba\u8a8d\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u4e0a\u8a18\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3092 Vite \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u914d\u7f6e\u3057\u3001<code>npm run dev<\/code> \u3067\u8d77\u52d5\u3059\u308b<\/li>\n<li>\u4f55\u3082\u5165\u529b\u305b\u305a\u9001\u4fe1 \u2192 \u5404\u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u5fc5\u9808\u30a8\u30e9\u30fc\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068<\/li>\n<li>\u4e0d\u6b63\u306a\u5f62\u5f0f\u306e\u30e1\u30fc\u30eb\u3092\u5165\u529b \u2192 \u5f62\u5f0f\u30a8\u30e9\u30fc\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068<\/li>\n<li>\u30d1\u30b9\u30ef\u30fc\u30c9\u3068\u78ba\u8a8d\u7528\u3092\u98df\u3044\u9055\u308f\u305b\u308b \u2192 <code>passwordConfirm<\/code> \u306b\u30a8\u30e9\u30fc\u304c\u51fa\u308b\u3053\u3068<\/li>\n<li>\u3059\u3079\u3066\u6b63\u3057\u304f\u5165\u529b\u3057\u3066\u9001\u4fe1 \u2192 <code>console.log<\/code> \u306b\u5024\u304c\u51fa\u529b\u3055\u308c\u3001\u30a8\u30e9\u30fc\u304c\u6d88\u3048\u308b\u3053\u3068<\/li>\n<\/ol>\n<h2>\u6ce8\u610f\u70b9<\/h2>\n<ul>\n<li><strong>\u65e2\u5b9a\u306f\u975e\u5236\u5fa1<\/strong>\u3002\u4ed6\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u7d44\u3080\u5834\u5408\u306f <code>Controller<\/code> \u3092\u631f\u3080\u524d\u63d0\u3067\u8a2d\u8a08\u3059\u308b<\/li>\n<li><code>watch<\/code> \u306e\u4e71\u7528\u306f\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u5897\u306b\u3064\u306a\u304c\u308b\u3002\u8868\u793a\u66f4\u65b0\u306b\u5fc5\u8981\u306a\u7bc4\u56f2\u306b\u7d5e\u308b<\/li>\n<li>\u521d\u671f\u5024\u306f <code>useForm({ defaultValues })<\/code> \u3067\u6e21\u3059\u3002\u7de8\u96c6\u753b\u9762\u3067\u306f API \u53d6\u5f97\u5f8c\u306b <code>reset(data)<\/code> \u3067\u6d41\u3057\u8fbc\u3080\u306e\u304c\u5b9a\u77f3<\/li>\n<li>\u30b9\u30ad\u30fc\u30de\u3068\u578b\u306e\u5358\u4e00\u30bd\u30fc\u30b9\u5316\u3092\u72d9\u3046\u306a\u3089 Zod \u3068\u306e\u4f75\u7528\u3092\u6700\u521d\u304b\u3089\u5165\u308c\u3066\u304a\u304f\u3068\u5f8c\u304c\u697d<\/li>\n<\/ul>\n<h2>\u307e\u3068\u3081<\/h2>\n<p>React Hook Form \u3092\u4f7f\u3046\u3068\u3001<code>useState<\/code> \u306e\u7f85\u5217\u30fb\u624b\u66f8\u304d\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30fb\u518d\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u554f\u984c\u3068\u3044\u3046\u300c\u30d5\u30a9\u30fc\u30e0\u3042\u308b\u3042\u308b\u300d\u306e\u5927\u534a\u3092\u89e3\u6d88\u3067\u304d\u307e\u3059\u3002\u307e\u305a <code>register<\/code> \u3068 <code>handleSubmit<\/code> \u3067\u7f6e\u304d\u63db\u3048\u3001\u6b21\u306b Zod \u3067\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u578b\u30921\u304b\u6240\u306b\u96c6\u7d04\u3059\u308b\u3001\u3068\u3044\u3046\u9806\u3067\u5c0e\u5165\u3059\u308b\u306e\u304c\u304a\u3059\u3059\u3081\u3067\u3059\u3002\u5c0f\u3055\u3044\u30d5\u30a9\u30fc\u30e0\u3067\u3082\u6069\u6075\u306f\u3042\u308a\u307e\u3059\u304c\u3001\u30d5\u30a3\u30fc\u30eb\u30c9\u6570\u304c\u5897\u3048\u308b\u307b\u3069\u5dee\u304c\u52b9\u3044\u3066\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>React \u3067\u30d5\u30a9\u30fc\u30e0\u3092\u4f5c\u308b\u3068\u3001useState \u3092\u5165\u529b\u6b04\u306e\u6570\u3060\u3051\u4e26\u3079\u3001onChange \u3092\u66f8\u304d\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u624b\u3067\u7d44\u307f\u3001\u30a8\u30e9\u30fc\u8868\u793a\u306e\u72b6\u614b\u3082\u5225\u9014\u7ba1\u7406\u3057\u2026\u2026\u3068\u3001\u3042\u3063\u3068\u3044\u3046\u9593\u306b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304c\u80a5\u5927\u5316\u3057\u307e\u3059\u3002React Hook Form\uff08\u4ee5\u4e0b\u2026<\/p>\n","protected":false},"author":1,"featured_media":3486,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","sitemap_hide":"","_veu_custom_css":"","veu_display_promotion_alert":"","vkexunit_cta_each_option":"","_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[36],"tags":[161,1161,1190,1094,376,1162],"class_list":["post-3487","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript-memorandum","tag-form","tag-react","tag-vite","tag-1094","tag-376","tag-1162"],"veu_head_title_object":{"title":"","add_site_title":""},"jetpack_publicize_connections":[],"jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/qol-kk.com\/wp2\/wp-content\/uploads\/2026\/09\/20260930-plan045-thumbnail.jpg","_links":{"self":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3487","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/comments?post=3487"}],"version-history":[{"count":1,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3487\/revisions"}],"predecessor-version":[{"id":3524,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3487\/revisions\/3524"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/media\/3486"}],"wp:attachment":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/media?parent=3487"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/categories?post=3487"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/tags?post=3487"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}