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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

React.js

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

Q&A

解決済

1回答

4117閲覧

react-hook-form useForm 値を受け取れない

hiroki88

総合スコア66

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2021/08/17 08:11

編集2021/08/18 14:06

◆バージョン
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-hook-form": "^7.12.1",

◆していること
・React Hook Formを使用してアカウント作成画面を作成しております。

・構造としてはわかりずらいかもしれませんが下記のように
アカウント作成画面のAccountCreate.tsxファイルと
入力(input)と登録(submit)のコンポーネントとしてformComponent配下に
formItems.tsxがあります。

my-appsrc配下formComponent配下
srcAccountCreate.tsx
formComponent
formItems.tsx

・見た目かこんな感じです。
イメージ説明

・コードは下記になります。
AccountCreate.tsx(見た目に関するコードは省略しています)

TypeScript

1import React, {ReactElement, useEffect, useState} from "react"; 2import { FormProvider, useForm } from 'react-hook-form'; 3import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; 4import Box from '@material-ui/core/Box'; 5import { FormInputComponent, FormSubmitComponent } from './formComponent/formItems'; 6 7type formInput = { 8 name: string; 9 searchId: string; 10} 11 12function AccountCreate(): ReactElement { 13 14 const methods = useForm<formInput>({ 15 defaultValues: { 16 name: '', 17 searchId: '', 18 }, 19 }); 20 21 const [input, setInput] = useState<formInput>({ 22 name: '', 23 searchId: '', 24 }); 25 26 const { handleSubmit, watch } = methods; 27 28 useEffect(() => { 29 setInput({ 30 name: watch('name'), 31 searchId: watch('searchId'), 32 }); 33 }, [watch('name'), watch('searchId')]); 34 35 return( 36 <section className={classes.section}> 37 <Box border={1} borderRadius="borderRadius" className={classes.box}> 38 <h1 className={classes.setFont}>アカウント作成</h1> 39 <FormProvider {...methods}> 40 <form className={classes.root} noValidate autoComplete="off" onSubmit={handleSubmit((data) => console.log(data))}> 41 <div className={classes.setMargin}> 42 <FormInputComponent labelText="名前" name="name" type="text" id={0} setClassName="js-account-icon" /> 43 <FormInputComponent labelText="ID" name="searchId" type="text" id={1} setClassName="js-search-icon" /> 44 <FormSubmitComponent submitText="登録"/> 45 </div> 46 </form> 47 </FormProvider> 48 </Box> 49 </section> 50 ); 51}; 52 53export default AccountCreate;

formItems.tsx(見た目に関するコードは省略しています)

TypeScript

1import React, { VFC } from "react"; 2import { useFormContext } from 'react-hook-form'; 3import TextField from '@material-ui/core/TextField'; 4import Grid from '@material-ui/core/Grid'; 5import AccountCircle from '@material-ui/icons/AccountCircle'; 6import SearchIcon from '@material-ui/icons/Search'; 7import Button from '@material-ui/core/Button'; 8import { withStyles, makeStyles, createStyles, Theme } from '@material-ui/core/styles'; 9// import { useContext } from "react"; 10 11const CssTextField = withStyles({ 12。。。 13})(TextField); 14 15type iProps = { 16 labelText: string; 17 name: string; 18 type: 'text' | 'password' | 'number' | 'submit'; 19 id: number; 20 setClassName: string; 21}; 22 23type sProps = { 24 submitText: string; 25}; 26 27export const FormInputComponent: VFC<iProps> = ({ 28 labelText, 29 name, 30 type, 31 id, 32 setClassName, 33}) => { 34 const { register } = useFormContext(); 35 36 const displayIcon = ()=>{ 37 if(id === 0){ 38 return <AccountCircle className={setClassName} />; 39 }else if(id === 1){ 40 return <SearchIcon className={setClassName} /> 41 } 42 }; 43 44 return( 45 <div className={classes.inputWrap}> 46 <Grid container spacing={1} className={classes.inputContainer}> 47 <Grid item> 48 {displayIcon()} 49 </Grid> 50 <Grid item> 51 <CssTextField required id="input-with-icon-grid" {...register(name, { required: true })} label={labelText} /> 52 </Grid> 53 </Grid> 54 </div> 55 ); 56}; 57 58export const FormSubmitComponent: VFC<sProps> = (({ 59 submitText, 60}) => { 61 62 return( 63 <div className={classes.buttonContainer}> 64 <Button className={classes.button} type='submit' variant="outlined">{submitText}</Button> 65 </div> 66 ); 67});

◆現在の状況
名前とIDを入力して登録ボタンをクリックしてもConsoleに入力情報が表示されないのと
watchでの値の監視ができておりません。
また下記の注意内容がConsoleに表示されております。

console

1@typescript-eslint/no-unused-vars 2 Line 76:6: React Hook useEffect has a missing dependency: 'watch'. Either include it or remove the dependency array react-hooks/exhaustive-deps 3 Line 76:7: React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked react-hooks/exhaustive-deps 4 Line 76:22: React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked react-hooks/exhaustive-deps 5 Line 76:41: React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked react-hooks/exhaustive-deps @typescript-eslint/no-unused-vars

◆解決したいこと
値を入力して登録ボタンをクリックしたらConsoleに入力情報が表示されたいのと
watchでの値の監視をできるようにしたいです。
自分が調べてみた限りコンポーネントをimportしネストしてuseFormを使用する時は
FormProviderとuseFormContextを使用することでコンポーネント先でもregister等を
使用できる認識でいます。
試しにimportせずにAccountCreate.tsxに直接input要素を記載し
値を入力して登録ボタンをクリックしたらConsoleに入力情報が表示され
watchでの値の監視もできていました。
なのでuseFormContextの書き方がおかしいのかと思っていますが調べてみても直し方が分かりません。
もし分かる方がいらっしゃればご教示頂きたいです。お願い致します。

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

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

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

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

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

guest

回答1

0

自己解決

解決したので原因を記載しておきます。
値が取得できない原因は下記のコードでした。

TypeScript

1<CssTextField required id="input-with-icon-grid" {...register(name, { required: true })} label={labelText} />

CssTextFieldはTextFieldコンポーネントにcssを適用させたものですが、自分はTextField=input要素という誤認識をしていました。実際はTextField=div要素であり、そのdiv要素の中にinput要素があるコンポーネントでした。
なのでregisterをCssTextFieldに指定しても値を受け取れていませんでした。(input要素にregisterを指定しないといけないため)
下記のようにinputPropsにregisterを設定することでinput要素にregisterが適用され値を受け取ることができました。

TypeScript

1<CssTextField required id="input-with-icon-grid" inputProps={{...register(name, { required: true })}} label={labelText} />

もし今後同じようにMaterial-UIとreact-hook-formを使用する場合は参考にして頂けると嬉しいです。

投稿2021/08/19 06:12

hiroki88

総合スコア66

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問