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

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

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

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

TypeScript

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

React.js

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

Q&A

2回答

540閲覧

useStateの初期化が面倒

vj2a6wk5

総合スコア5

JavaScript

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

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2023/11/15 23:43

編集2023/11/15 23:51

実現したいこと

以下(1)のような任意typeに対して、以下(2)のように初期値を指定する必要があります。
初期値を自動的に指定する事は可能でしょうか?
そもそも、初期値を定義しなくても良い方法はありますでしょうか?

初期値はnumberであれば0, stringであれば''のように、毎回同じ値を指定しているので毎回初期値を指定する事は面倒だと感じています。

  • (1) 任意type

TypeScript

1type User = { 2 id: number; 3 name: string; 4};
  • (2) 初期値を設定する必要がある

TypeScript

1const [user, setUser] = useState<User>({ 2 id: 0, 3 name: '', 4});

発生している問題

上記Userのように2つの要素だけであれば数が少ないので楽ですが、実際は多くのtypeが存在して、多くのuseStateが存在しています。
初期値はnumberであれば0, stringであれば''のように、毎回同じ値を指定しているので毎回初期値を指定する事は面倒だと感じています。

また、typeを変更した時、typeが複数ファイルで利用されている場合は全て修正する必要があり、とても面倒です。

初期値を自動的に設定する方法、または、初期値を定義しなくてよい方法を探しています。
または、そもそもの話として初期値を指定することを考えるのはアンチパターンになるのでしょうか?
みなさんはundefinedが前提でコードを書いていますでしょうか?

該当のソースコード

https://stackblitz.com/edit/vitejs-vite-vpsnw7?file=src%2FApp.tsx

試したこと

  • typeに存在する全てのプロパティ名をstring[]として取得して自動生成を試みましたが不可能でした

https://teratail.com/questions/4l8f3owrh9nvcd

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

  • Visual Studio Code 1.81.1
  • React.js 18.2.0
  • TypeScript 5.2.2

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

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

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

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

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

guest

回答2

0

typeに存在する全てのプロパティ名をstring[]として取得して自動生成を試みましたが不可能でした

えっと、前の質問にも解答したとおり、「値から型を作る」手段で対応できるかもしれません。

typescript

1const numberKeys = ['id'] as const; 2const stringKeys = ['name'] as const; 3 4type Composed<N extends string, S extends string> = { 5 [k in N]: number; 6} & { 7 [k in S]: string 8} 9 10type User = Composed<(typeof numberKeys)[number], (typeof stringKeys)[number]>; 11 12const initialize = <N extends readonly string[], S extends readonly string[]>( 13 numbers: N, strings: S 14): Composed<N[number], S[number]> => Object.fromEntries([ 15 ...numbers.map(key => [key, 0]), 16 ...strings.map(key => [key, '']) 17]) as Composed<N[number], S[number]>; 18 19const emptyUser = initialize(numberKeys, stringKeys);

投稿2023/11/16 00:39

maisumakun

総合スコア146544

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

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

0

Avoid Hasty Abstraction (早まった抽象化は避けよう)という標語があります。共通化するべきでない物事についてのコードを共通化すると、コードが格段に複雑化して扱いにくくなるのでトレードオフを考えて、まずは「共通化せずベタ書きする」ことから始めるほうが良い、という教訓です。

抽象化・共通化によってメンテナンス性の向上につながる重複コードは削減できると良いですが、「意味的には別にまとめるほどじゃない」「愚直に書いたほうがパッと見ただけで意味が明確である」ようなケースではむしろ技巧を凝らせすぎて理解しづらいコードにならないように、愚直に書いたほうが良いです。

今回のように「入力フォームの初期値に 0"" を入れる」は明確に後者です。もともと長くないので大したコード削減になりませんし、「本質的に number なら 0, string なら "" しかありえない」訳ではない、つまり 意味は重複していないので、共通化するうまみがありません。


強いていうなら、「Derived State の場合は useState を使わない」というベストプラクティスや、「フォームなら react-hook-form」「データ取得等(fetch と mutation)なら useSWR / TanStask Query」のように具体的な切り口でライブラリに頼ってコードを、特にステートの数を減らすと楽になります。

ステートの個数が増えるにつれて爆発的ににコンポーネントの複雑さが増すので。

投稿2023/11/17 15:30

編集2023/11/17 15:31
honey32

総合スコア246

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問