質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

970閲覧

RHF×MaterialUIのラジオボタンにAPIで取得した初期値を設定したい

to__fu

総合スコア6

Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2024/01/17 15:47

実現したいこと

RHF×MaterialUIで作成しているフォームのラジオボタン項目に、
APIで取得した値を初期値として設定したい

発生している問題・分からないこと

react-hook-formとMaterialUIを利用してフォームを作成しています。
ラジオボタン項目にAPIで取得した値を初期値として設定したいですが、やり方がわかりません。

該当のソースコード

TypeScript

1import React, { useState } from 'react' 2import { 3 Container, 4 Stack, 5 TextField, 6 FormControl, 7 FormControlLabel, 8 RadioGroup, 9 Radio, 10} from '@mui/material'; 11import { useForm, Controller } from 'react-hook-form' 12import * as yup from 'yup'; 13import { yupResolver } from '@hookform/resolvers/yup' 14 15import client from '../lib/api/client'; 16 17const UserInfo = () => { 18 19 // フォームの型 20 class UserFormData { 21 name: string = '' 22 sex: number = 1 23 } 24 25 // バリデーションルール 26 const UserSchema = yup.object({ 27 name: yup 28 .string() 29 .required(), 30 sex: yup 31 .number() 32 .required() 33 }); 34 35 // 初期表示データ取得 36 const initDisplayData = async (userId: string) => { 37 try { 38 const result = await client.get(`users/${userId}`); 39 const data = result.data.data; 40 return { 41 name: data.name, 42 sex: data.sex, 43 } as UserFormData; 44 } catch (error) { 45 console.log("取得失敗"); 46 return new UserFormData(); 47 } 48 } 49 50 const { 51 register, 52 control, 53 formState: { errors }, 54 } = useForm({ 55 mode: 'all', 56 resolver: yupResolver(UserSchema), 57 defaultValues: async() => initDisplayData('1') // TODO: 58 }) 59 60 return ( 61 <Container maxWidth="sm" sx={{ pt: 5 }}> 62 <Stack spacing={3}> 63 64 <TextField 65 required 66 label="氏名" 67 InputLabelProps={{ shrink: true }} 68 {...register('name')} 69 error={"name" in errors} 70 helperText={errors.name?.message} 71 /> 72 73 <Controller 74 name='sex' 75 control={control} 76 render={({field}) => ( 77 <FormControl> 78 <RadioGroup 79 row 80 aria-label="sex" 81 defaultValue={2} // TODO: ここにAPIからの初期値を設定したい 82 {...field} 83 > 84 <FormControlLabel value={1} control={<Radio />} label="男性" /> 85 <FormControlLabel value={2} control={<Radio />} label="女性" /> 86 <FormControlLabel value={3} control={<Radio />} label="その他・未回答" /> 87 </RadioGroup> 88 </FormControl> 89 )} 90 /> 91 </Stack> 92 </Container> 93 ) 94} 95export default UserInfo

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

defaultValue={2} と固定値を設定している箇所を
defaultValue={field.value} や defaultValue={getValues('sex')} としてもラジオボタンは未選択の状態でした。

また、initDisplayData の中で「sex」というstateを設定し、defaultValueに渡してもラジオボタンは何も選択されていない状態でした。

TextFieldの項目の方には取得した初期値が設定されます。

補足

react, react-hook-formの扱い自体あまり慣れていないため、的外れなことをしていたらすみません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決。reset使うことで初期値が反映されました。
とりあえずやりたいことは実現できたけど、これで合ってるんだろうか。。

import React, { useState } from 'react' import { Container, Stack, TextField, FormControl, FormControlLabel, RadioGroup, Radio, } from '@mui/material'; import { useForm, Controller } from 'react-hook-form' import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup' import client from '../lib/api/client'; const UserInfo = () => { // フォームの型 class UserFormData { name: string = '' sex: number = 1 } // バリデーションルール const UserSchema = yup.object({ name: yup .string() .required(), sex: yup .number() .required() }); const [data, setData] = useState<UserFormData>(new UserFormData); useEffect(() => { (async() => { const response = await initDisplayData(1); setData(response) })() },[]) useEffect(() => { reset(data) }, [data]) // 初期表示データ取得 const initDisplayData = async (userId: string) => { try { const result = await client.get(`users/${userId}`); const data = result.data.data; return { name: data.name, sex: data.sex, } as UserFormData; } catch (error) { console.log("取得失敗"); return new UserFormData(); } } const { register, control, reset, formState: { errors }, } = useForm({ mode: 'all', resolver: yupResolver(UserSchema), defaultValues: { sex: data.sex } }) return ( <Container maxWidth="sm" sx={{ pt: 5 }}> <Stack spacing={3}> <TextField required label="氏名" InputLabelProps={{ shrink: true }} {...register('name')} error={"name" in errors} helperText={errors.name?.message} /> <Controller name='sex' control={control} render={({field}) => ( <FormControl> <RadioGroup row aria-label="sex" value={filed.value} > <FormControlLabel value={1} control={<Radio />} label="男性" {...register('sex')} /> <FormControlLabel value={2} control={<Radio />} label="女性" {...register('sex')} /> <FormControlLabel value={3} control={<Radio />} label="その他・未回答" {...register('sex')} /> </RadioGroup> </FormControl> )} /> </Stack> </Container> ) } export default UserInfo

投稿2024/02/01 13:14

編集2024/02/01 13:18
to__fu

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問