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

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

新規登録して質問してみよう
ただいま回答率
85.48%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

解決済

1回答

1292閲覧

ステートフック利用時、入力フォームをマップで回している際のフォームコントロールについて

nerianighthawk

総合スコア544

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2019/08/19 07:50

編集2019/08/19 08:21

前提・実現したいこと

React で複数の入力欄を生成する際に、map で回したいと考えています。
また、各入力フォームをステートフックを利用して value パラメータに与えようとしています。
しかし、私の実装では uncontrolled input warning が発生してしまい、上記2点を両立させる方法がわかりません。

発生している問題・エラーメッセージ

通常、テキストフィールドでステートを使いたい場合は value パラメータに値を与え、onChange パラメータでセッタを実行すると思います。
上記の操作を行わないと、value パラメータに与えられている値が undefined になってしまう瞬間があり、uncontrolled input warning が発生してしまうという認識です。
今回はテキストフィールドを map で回したいため、value に与えるステートの値や onChange で実行するセッタをその都度違うものにする必要があります。
上記条件で uncontrolled input warning にならない方法がわからない状態です。

該当のソースコード

ソースコードは以下の通りです。
ステートフックで userIdmail を用意して、TextField に必要な情報も一緒に混ぜて配列にして map で回しています。
getUser は ajax 通信でユーザ情報を取って来ています。

TypeScript

1const createForm: Function = ( 2 id: keyof User, 3 label: string, 4 type: string, 5 value: string, 6 setter: Function 7): InputForm<User> => ({ 8 id: id, 9 label: label, 10 type: type, 11 value: value, 12 setter: setter 13}) 14 15const getUserParam = (setUserId: Function, setMail: Function) => { 16 getUser().then(user => { 17 setUserId(user.userId) 18 setMail(user.mail) 19 }) 20} 21 22const handleChange = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>, setter: Function) => { 23 const value = event.currentTarget.value 24 setter(value) 25} 26 27const UserSetting = () => { 28 const [userId, setUserId] = useState('') 29 const [mail, setMail] = useState('') 30 31 useEffect(() => getUserParam(setUserId, setMail), []) 32 33 const paramList = [ 34 createForm(KEY_USERID, FORM_USERID, 'text', userId, setUserId), 35 createForm(KEY_MAIL, FORM_MAIL, 'text', mail, setMail) 36 ] as InputForm<User>[] 37 38 const userForm = paramList.map(param => ( 39 <div key={param.id}> 40 <TextField 41 label={param.label} 42 value={param.value} 43 type={param.type} 44 onChange={(e) => handleChange(e, param.setter)} 45 fullWidth={param.id === KEY_MAIL} 46 /> 47 </div> 48 )) 49 50 return ( 51 <Paper className='fullheight'> 52 <Typography variant="h5"> 53 {SETTING_USER} 54 </Typography> 55 {userForm} 56 </Paper> 57 ) 58} 59 60export default UserSetting

試したこと

上記ソースで uncontrolled input warning が出たことから、value パラメータに指定する値はステートフックで用意した変数そのものでないといけないのかなと思いました(ステートフックの仕様をちゃんと理解できていないのですが、間接参照がダメなんでしょうか…?)。
試しに、リストで持っている値ではなく、map の 内部で param.id の値で場合分けをして、別変数に一度格納する方法を試しましたが、結果は変わりませんでした。
何かやり方があるのであれば、知りたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

あまり参考にならないかもしれませんが、code sandboxにサンプルプロジェクトを作ってみました。
getUser()関数の返り値にちゃんとした値が入ってくる限りは、この環境だと特にエラーもなく実行できました。(不明な部分は適当に補完しているので、この環境が正しいとは限りませんが・・・)

ただ、上記のサンプルプロジェクトのUserSetting.tsxの16,17行目がnullになっていると uncontrolled input warning が発生するので、getUser()関数の返り値の中でnullが入ってきていないかを確認してみるのが良いかもしれません。

もしその場合は以下のように書くことでエラーを回避できると思います。

getUser().then(user => { setUserId(user.userId || '') // userIdがnullやundefの場合は空文字を入れるようにする setMail(user.mail || '') // 同上 })

投稿2019/08/19 14:41

編集2019/08/19 14:51
KuwabataK

総合スコア306

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

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

nerianighthawk

2019/08/19 23:48

回答ありがとうございます。 受け取ったキー名が userId ではなく username、mail ではなく email でした。 userに値が入っていることは確認していたので、そんなはずないと思っていたのですが、User型のキー名とAPIのキー名が一致していなかったことが原因ですね…
KuwabataK

2019/08/20 00:58 編集

あ、APIのレスポンスの中身と型が一致していないというあるあるなやつですね 直ってよかったです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問