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

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

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

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

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

TypeScript

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

React.js

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

Q&A

解決済

2回答

4108閲覧

React(Nextjs)でフォーム実装でuseStateとuseCallbackを用いて入力された値を親コンポーネントで出力したい

TatsuyaOkawa

総合スコア29

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

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

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2021/06/26 05:44

編集2021/06/26 06:23

next.jsで実装していましてinputselectを子コンポーネントとして読み込みフォームを作成しています。

子コンポーネントの入力された値を親コンポーネントで受け取り、inputContentinputStatusでそれぞれconsoleに出力しています。その際に実際に入力された文字とconsoleに出力した文字が以下のようにズレてしまいます。(表示されて欲しい値の1つ前の値)

入力された文字列console出力された値
a
aaa
aaaaa
aaaaaaa

設定されているevent.currentTarget.value(event.target.valueでも同様)を出力すると入力された文字同様の値がconsole出力されるので、入力値はちゃんと渡って来ていると思います。
この状態はコード上どこか間違っているのでしょうか?それともそいう挙動をするものなのでしょうか?

まだチュートリアル卒業レベルなので初歩的な質問かとは思うのですが気になって進めそうにないのでどなたか教えてもらえると嬉しいです。

以下が今書いてみているコードになります。
不足あれば追加しますのでコメントでご指摘いただければと思います。

どうぞよろしくお願いいたします。

親コンポーネント
import { useCallback, useState } from 'react'; import { SelectBox, TextField } from './forms'; const Filter = () => { const [text, setText] = useState(''); const [status, setStatus] = useState(''); const inputText = useCallback( (event: React.ChangeEvent<HTMLInputElement>) => { setText(event.currentTarget.value); console.log(text); }, [text, setText], ); const inputStatus = useCallback( (event: React.ChangeEvent<HTMLSelectElement>) => { setStatus(event.currentTarget.value); console.log(status); }, [status, setStatus], ); return ( <> <div> <TextField label={'内容'} placeholder={'内容を入力'} type={'text'} onChange={inputText} /> </div> <div> <SelectBox label="ステータス" value={status} select={inputStatus} /> </div> </> ); };
子コンポーネント(TextFiled.tsx)
interface Props { label: string; placeholder: string; type: string; onChange: (event: React.ChangeEvent<HTMLInputElement>) => void; } const TextField = (props: Props) => { return ( <> <label>{props.label}</label> <input type={props.type} placeholder={props.placeholder} onChange={(event) => props.onChange(event)} /> </> ); };
子コンポーネント(selectBoxs.tsx)
interface Props { id?: string; label: string; select: (event: React.ChangeEvent<HTMLSelectElement>) => void; value: string; } const SelectBox = (props: Props) => { return ( <> <label>{props.label}</label> <select value={props.value} onChange={(event) => props.select(event)} > <option>1</option> <option>2</option> <option>3</option> </select> </> ); };

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

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

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

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

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

guest

回答2

0

ベストアンサー

クラスコンポーネントで setState した場合や、 useState フックを利用し State を更新するときの更新処理は、非同期で行われます。

どういうことかというと、

js

1setText(event.currentTarget.value); 2console.log(text);

と書いたとき、 すぐ Text に値がセットされ console.log が呼び出されるわけではないということです。

今回のケースでは、値のセットが後回しにされて、先走って console.log が呼び出された結果、1つ前の値が表示されたのではないかと考えられます。

単に現在の値を表示したいのであれば、 event.currentTarget.value を直接表示するか、

js

1import { useCallback, useState, useEffect } from 'react'; 2 3/* ... */ 4 5const inputText = useCallback( 6 (event: React.ChangeEvent<HTMLInputElement>) => { 7 setText(event.currentTarget.value); 8 }, 9 [text, setText] 10); 11 12useEffect(() => { 13 console.log(text); 14}, [text]);

useEffect フックを使って、 text が更新されたタイミングで console.log が呼び出されるようにできます。

投稿2021/06/26 06:37

coolwind0202

総合スコア708

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

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

TatsuyaOkawa

2021/06/27 07:30

分かりやすいご説明ありがとうございます! `useEffect` の件も全く想像していなかたので勉強になりました。ありがとうございます!
guest

0

この状態はコード上どこか間違っているのでしょうか?それともそいう挙動をするものなのでしょうか?

どちらもYesです。

useStateによるstateの変更処理は非同期に行われるものなので、setStateの直後にconsole.logを置いた場合、変更前の値が出力されます。

投稿2021/06/26 06:34

maisumakun

総合スコア146018

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

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

TatsuyaOkawa

2021/06/27 07:28

> useStateによるstateの変更処理は非同期に行われるもの この事実を知りませんでした! そこを理解すると当然の結果ということですね。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問