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

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

新規登録して質問してみよう
ただいま回答率
85.46%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

React.js

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

Q&A

解決済

2回答

1163閲覧

React onchageとHooksの挙動に関して

front

総合スコア12

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

React.js

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

0グッド

0クリップ

投稿2020/08/05 01:42

編集2020/08/05 01:54

##React onChange&Hookの挙動について

勉強の一貫でReactを使用したFormを作成しています。
inputタグにonChangeによって値を取得し、Hooksで値を保持する構成で記載しています。

しかし挙動がおかしく、下記問題を解決したいと考えています。

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

inputタグで入力した値と、onChangeとHooksでの値保持で整合性が取れていない。
おそらくonChangeとHooksの挙動についての理解度不足だと思いますので、ご教授いただけると幸いです。

■問題ケース
[User]
・入力値 test01 (6文字入力)
→6文字入力するもエラー文が消えてくれない

[pass]
・入力値 testpass (8文字入力)
→6文字入力するもエラー文が消えてくれない

[passCheck]
・入力値 testpass (8文字入力)
→passと入力値が同じはずなのに、不一致エラーが発生。

該当のソースコード

React

1import React, { useState } from "react"; 2import ReactDOM from "react-dom"; 3 4function Form() { 5 let errorMessage = <p></p>; 6 7 const [user, inputUser] = useState(""); 8 const [pass, inputPass] = useState(""); 9 const [PassCheck, inputPassCheck] = useState(""); 10 const str = /^[0-9a-zA-Z]*$/; 11 12 const handleUserChange = (e: React.FocusEvent<HTMLInputElement>) => { 13 inputUser(e.target.value); 14 15 if (str.test(user) === false || user.length < 6 || user.length > 32) { 16 errorMessage = <p>条件と合わないためエラー</p>; 17 } else { 18 errorMessage = <p></p>; 19 } 20 ReactDOM.render(errorMessage, document.getElementById("errorUserMessage")); 21 }; 22 const handlePassChange = (e: React.ChangeEvent<HTMLInputElement>) => { 23 inputPass(e.target.value); 24 25 if (str.test(pass) === false || pass.length < 7) { 26 errorMessage = <p>条件と合わないためエラー</p>; 27 } else { 28 errorMessage = <p></p>; 29 } 30 ReactDOM.render(errorMessage, document.getElementById("errorPassMessage")); 31 }; 32 const handlePassCheck = (e: React.ChangeEvent<HTMLInputElement>) => { 33 inputPassCheck(e.target.value); 34 35 if (!(PassCheck === pass)) { 36 errorMessage = <p>不一致エラー</p>; 37  } else { 38 errorMessage = <p></p>; 39 } 40 ReactDOM.render(errorMessage, document.getElementById("errorPassCheck")); 41 }; 42 43 44 return ( 45 <form action="" id="form"> 46 <input type="text" value={user} onChange={handleUserChange} /> 47 <p id="errorUserMessage"></p> 48 <input type="text" onChange={handlePassChange} /> 49 <p id="errorPassMessage"></p> 50 <input type="text" onChange={handlePassCheck} /> 51 <p id="errorPassCheck"></p> 52 </form> 53 ); 54} 55 56export default Form; 57

試したこと

関数コンポーネントとHooksによる値管理を実施。
しかし、挙動が意図しないためクラスコンポーネントに変更するもうまくいかず。

お手数かけますが、ご教授いただけると幸いです。
よろしくお願いいたします。

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

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

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

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

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

maisumakun

2020/08/05 01:48

えっと、export defaultしているはずのFormの定義はどこでしょうか?
front

2020/08/05 01:54

失礼いたしました。 修正対応いたしましたので、ご確認お願いいたします
guest

回答2

0

ベストアンサー

let errorMessage = <p></p>;

のような管理をして再代入を行うとReact は挙動が保証されません。
あと@maisumakun さんがおっしゃってるように今回のような場合は ReactDOM.render は使いません。

js

1import React, { useState } from "react"; 2 3function Form() { 4 5 const [user, inputUser] = useState(""); 6 const [pass, inputPass] = useState(""); 7 const [PassCheck, inputPassCheck] = useState(""); 8 9 const [errorUserMessage, setErrorUserMessage] = useState<string>('') 10 const [errorPassMessage, setErrorPassMessage] = useState<string>('') 11 const [errorPassCheck, setErrorPassCheck] = useState<string>('') 12 const str = /^[0-9a-zA-Z]*$/; 13 14 const handleUserChange = (e: React.FocusEvent<HTMLInputElement>) => { 15 inputUser(e.target.value); 16 17 if (str.test(user) === false || user.length < 6 || user.length > 32) { 18 errorUserMessage("条件と合わないためエラー") 19 } else { 20 setErrorUserMessage("") 21 } 22 }; 23 const handlePassChange = (e: React.ChangeEvent<HTMLInputElement>) => { 24 inputPass(e.target.value); 25 26 if (str.test(pass) === false || pass.length < 7) { 27 errorPassMessage("条件と合わないためエラー") 28 } else { 29 setErrorPassMessage("") 30 } 31 }; 32 const handlePassCheck = (e: React.ChangeEvent<HTMLInputElement>) => { 33 inputPassCheck(e.target.value); 34 35 if (!(PassCheck === pass)) { 36 errorPassCheck("不一致エラー") 37 } else { 38 setErrorPassCheck("") 39 } 40 }; 41 42 return ( 43 <form action="" id="form"> 44 <input type="text" value={user} onChange={handleUserChange} /> 45 <p id="errorUserMessage"><p>{errorUserMessage}</p></p> 46 <input type="text" onChange={handlePassChange} /> 47 <p id="errorPassMessage"><p>{errorPassMessage}</p></p> 48 <input type="text" onChange={handlePassCheck} /> 49 <p id="errorPassCheck"><p>{errorPassCheck}</p></p> 50 </form> 51 ); 52} 53 54export default Form;

追記

eventハンドラ関数の中を呼ばれたタイミングでは変数が更新されていないため1回遅れています。

const newPass = e.target.value if (str.test(newPass) === false || newPass.length < 7) {

とするか

または

useEffect(() => { if (str.test(pass) === false || pass.length < 7) { // ... }, [pass])

というふうに useEffect 内でバリデーションするかに変えてみてください。

投稿2020/08/05 02:54

編集2020/08/05 05:59
anozon

総合スコア662

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

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

front

2020/08/05 04:19

記述方法についてご指摘ありがとうございます。 修正対応いたします。 本題であるform入力時の挙動について、私の力足らずで解決できておりません。 お手数ですがこちらについても指摘いただけると幸いです。 ■問題ケース [User] ・入力値 test01 (6文字入力) →6文字入力するもエラー文が消えてくれない。  7文字目を入力するとエラー文が消える。 [pass] ・入力値 testpass (8文字入力) →8文字入力するもエラー文が消えてくれない 9文字目を入力するとエラー文が消える。 [passCheck] ・入力値 testpass (8文字入力) →passと入力値が同じはずなのに、不一致エラーが発生。 9文字目を入力すると一致となる(その際に一致していなくても正常となる)
anozon

2020/08/05 05:59

追記しました
front

2020/08/06 00:09

ありがとうございます。 @maisumakun @anozon様のおかげで解決することができました。 細かい記載方法まで提示していただきありがとうございました。 未熟者ですが引き続き精進して参ります。
guest

0

なぜイベント内からReactDOM.renderを行っているのでしょうか。通常は値をstateに持たせて、それで仮想DOMを書き換えれば済む話かと思います。

投稿2020/08/05 01:59

maisumakun

総合スコア145208

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

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

front

2020/08/05 04:20

記述方法についてご指摘ありがとうございます。 修正対応いたします。 本題であるform入力時の挙動について、私の力足らずで解決できておりません。 お手数ですがこちらについても指摘いただけると幸いです。 ■問題ケース [User] ・入力値 test01 (6文字入力) →6文字入力するもエラー文が消えてくれない。  7文字目を入力するとエラー文が消える。 [pass] ・入力値 testpass (8文字入力) →8文字入力するもエラー文が消えてくれない 9文字目を入力するとエラー文が消える。 [passCheck] ・入力値 testpass (8文字入力) →passと入力値が同じはずなのに、不一致エラーが発生。 9文字目を入力すると一致となる(その際に一致していなくても正常となる)
maisumakun

2020/08/05 22:56

> 本題であるform入力時の挙動について いえ、それも「ReactDOM.renderで無理やり出力している」ことが要因だ、という趣旨の回答です。
front

2020/08/06 00:08

ありがとうございます。 @maisumakun @anozon様のおかげで解決することができました。 ご教授いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問