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

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

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

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

React.js

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

Q&A

1回答

5165閲覧

Material UIのTextFieldのdefaultValueについて

caren

総合スコア25

Material-UI

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

React.js

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

0グッド

0クリップ

投稿2022/11/24 05:26

編集2022/11/27 23:57

前提

reactでMaterial UIのTextFieldを使って開発しています。
TextFieldのdefaultValueという属性を使用したいのですが、一方はうまくいっているのに対して、他方はうまくいっておりません。
コードが長すぎるため、必要だと思うところのみコードを載せますので、載せていない部分のコードが必要であれば教えてください。

label="お客様コード" の方のTextField だとdefaultValueを設定できるが、label="担当者"の方のTextFieldのdefaultValueが設定できません。

Material UIのdefaultValueのドキュメントをみると、「Use when the component is not controlled」と書かれているが、それが原因なのでしょうか?よくわからず困っています。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • TextFieldにdefaultValueを設定したい

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

エラーメッセージ

該当のソースコード

test.jsx

1 2import { NohinHeaderContext } from '../../providers/setNohinHeaderProvider'; 3import { useGetNohinHeaderInfo } from '../../../hooks/useGetNohinheaderInfo'; 4import {TextField} from '@mui/material'; 5 6 const { nohinHeader, setNohinHeader } = useContext(NohinHeaderContext); 7 8 useGetNohinHeaderInfo(); 9 10export const test =() =>{ 11 12return( 13 <TextField variant="standard" label="自社担当者" sx={{ m: 1 }} 14 defaultValue={nohinHeader.representative} /> ★ 15 16); 17} 18

useGetNohinheaderInfo.js

1import { useContext, useEffect } from "react"; 2 import {NohinHeaderContext} from '../components/providers/setNohinHeaderProvider'; 3 4export const useGetNohinHeaderInfo =() =>{ 5 6 const {nohinHeader, setNohinHeader}=useContext(NohinHeaderContext); 7 let newData = {}; 8 useEffect(() => { 9 fetch('getnohinheaderinfo.php', { method: 'POST', mode: 'cors', credentials: 'include' } 10 ) 11 .then(response => { 12 if (!response.ok) { 13 throw new Error(`${response.status} ${response.statusText}`); 14 } 15 return response.json(); 16 }) 17 .then(data => { 18 console.log('** fetch: then(data)'); 19 console.log(data); 20 newData={indexno:data.index_no,voucherno:data.voucher_no,customerid:data.customer_id,issueddate:data.issued_date, 21 representative:data.representative,taxr:data.tax_r,taxs:data.tax_s,subtotals:data.subtotal_s,subtotalr:data.subtotal_r, 22 taxamounts:data.tax_amount_s,taxamountr:data.tax_amount_r,totalnotax:data.total_notax,taxamount:data.tax_amount,totalamount:data.total_amount} 23 setNohinHeader(newData); 24 }) 25 .catch((reason) => { 26 console.log('** fetch: catch'); 27 console.log(reason); 28 }); 29 }, []); 30 31 return true; 32}

setNohinHeaderProvider.jsx

1 2import { createContext, useState } from "react"; 3 4export const NohinHeaderContext = createContext({}); 5 6export const SetNohinHeaderProvider = props => { 7 const { children } = props; 8 9 const [nohinHeader, setNohinHeader] = useState({ 10 indexno:"",voucherno: "", customerid: "", issueddate: "", representative: "", 11 taxr: "",taxs:"",subtotals:"",subtotalr:"",taxamounts:"",taxamountr:"", 12 totalnotax:"",taxamount:"",totalamount:"", 13 }); 14 15 return ( 16 <NohinHeaderContext.Provider value={{ nohinHeader, setNohinHeader}}> 17 {children} 18 </NohinHeaderContext.Provider> 19 ); 20 21}; 22

試したこと

★のTextFieldに対してdefaultValueではなくvalue={nohinHeader.representative}とするとカスタムフックから取得した値はきちんと取れてきている。

補足情報(FW/ツールのバージョンなど)

"@mui/material": "^5.10.8",
"react": "^18.2.0",

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

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

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

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

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

yuki23

2022/11/24 14:31

なぜ value ではなく defaultValue を設定したいのでしょうか?
caren

2022/11/24 23:41

valueだと値の設定は可能ですが、入力ができない(変更不可)となってしまうからです。defaultValueだと入力ができます。
yuki23

2022/11/25 04:21

「設定できない」とは具体的に何が発生しているのでしょうか?
caren

2022/11/25 04:23

値が何も表示されない状態ということです。エラーはありません。
yuki23

2022/11/25 10:15

const test = nohinHeader["representative"]; //自作のカスタムフックから値を取得 この部分はどこから、どうやって、どのような値が取得されるのでしょうか? 質問文にソースコードを提示してください。
caren

2022/11/28 00:04 編集

コードが長くなってしまいますが、必要そうであるところを載せました。 また、質問の便宜上、最初はlabel="お客様コード" の方のTextFieldとlabel="自社担当者"の方のTextFieldを同じjsx内に記述しましたが、実際のソース上では別のjsxに記載されています。どちらのTextFieldもdefaultValueに設定している値はuseContextでグローバルに管理しているものです。この値は自分が作成したphpにfetchでPOSTを送る形で取得しており、phpは自作のDBにアクセスしてその結果をカスタムフックに返しているという構造になります。nohinHeaderの値自体はデバッグで値が取得できていることは確認済みです。他にも回答のために必要なコードがあれば教えてください。
guest

回答1

0

ご提示のソースを要約すると、問題点は最初に test コンポーネントを描画したときに defaultValue の値は空文字列であるということだと思います。
defaultValue は最初に指定したときの値をコンポーネントの初期値とし、それ以降はコンポーネントが値を制御します。その後に値を変えてもコンポーネントに表示される値は変わりません(それが "not controlled" という言葉の意味です)。つまり、最初に描画したときに空文字列だったなら、それ以降はユーザー操作などがない限りずっと空文字列のままです。

解決策としては、次のどちらかになると思われます。基本的には、複雑なことがしたいなら controlled component にするのが推奨です。

  1. defaultValue を使わず value を使う(controlled component として使う)
  2. defaultValue が確定するまで test コンポーネントを描画しない

投稿2022/11/28 13:06

yuki23

総合スコア1448

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

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

caren

2022/11/28 23:57

解決策のご提示ありがとうございます。 解決策の1に関しては、value={nohinHeader.representative}とし、onChangeでsetNohinHeader を呼び、target.valueを設定すれば、初期値がnohinHeader.representativeで表示され、かつユーザーからの入力を受け付けることが可能であることを試しました。しかし実際はtestコンポーネントには他にも沢山のTextFieldなどがあり、そのすべてにdefaultValueを設定したいため、ユーザーが入力する度にonChangeイベントが発火するのはあまり意味がない気がしています。(onChangeの度に何かしたい処理があれば意味があるとは思うのですが、testコンポーネントは最終的にtestコンポーネント内にあるいくつかのTextFieldに入力された値をサーバーにPOSTするというコンポーネントにしたいと考えているため) そのため、解決策で提示してくださった2で解決したいと思っているのですが、なぜtestコンポーネントが描画されたときにdefaultValueの値が空なのかがわかっておりません。defaultValueで設定されているnohinHeaderは、testコンポーネント内の useGetNohinHeaderInfo();のタイミングで取得されており、useGetNohinheaderInfo.jsではuseEffectの中でnohinHeaderをセットしています。私の認識ではDBなどから値を取得したいときはuseEffectを使用した方がよいというのをどこかで目にしました。useEffectはtestコンポーネントがすべて描画されてから実行されているため、defaultValueが初期値(つまり空)のままになっているという認識で合っていますか?
yuki23

2022/11/29 11:37

> useEffectはtestコンポーネントがすべて描画されてから実行されているため、defaultValueが初期値(つまり空)のままになっているという認識で合っていますか? そうです。 useEffect はその中に書いてある処理を後で実行することを予約するだけであって、それを呼んだ時点ではまだ実行されていないし、ましてやfetchが終わるのを待っているわけでもないということです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問