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

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

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

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

JavaScript

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

React.js

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

Q&A

解決済

2回答

1035閲覧

[React]配列としてのstateにオブジェクトを追加したいが、そのやり方がわからない

moyong

総合スコア19

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2021/02/23 11:00

編集2021/02/23 11:45

Reactそのものや配列・オブジェクトについてまだまだ理解できておらず、見当違いなことを言っているかもしれません。
アドバイスいただけると幸いです。

問題

trainingRecordsステート(配列)に
trainingRecordステート(オブジェクト)を追加したいのですが、型エラー?がでてしまいます。

trainingRecords

1const [ trainingRecords, setTrainingRecords ] = useState([]);

trainingRecord

1const [ trainingRecord, setTrainingRecord ] = useState({ 2 trainingName: "", 3 trainingWeight: "none", 4 trainingReps: "0", 5})

saveTrainingRecord

1const saveTrainingRecord = () => { 2 if (!trainingRecords.length) { 3 setTrainingRecords(trainingRecord); 4 } else { 5 const newRecord = {...trainingRecords, trainingRecord}; 6 setTrainingRecords(newRecord); 7 } 8};

イメージ説明
saveTrainingRecordメソッドの中の書き方が間違っているためだと思われるのですが、どう書けばいいでしょうか?

備考

前回質問させていただいたものを、いただいた修正依頼をもとに作り直させていただきました。
筋トレSNSなるものをつくっていまして、
トレーニング名、重量、回数を入力フォームから受け取って格納するのがtrainingRecord、
それを複数格納して、最終的にデータベースに保存するのがtrainingRecordsです。

回答への返信

siruku6さん、ありがとうございます。
[]をつけてみると、
イメージ説明
このように型'never'に割り当てられませんとでてしまいました。

そこで、もはや意味もわからずtrainingRecordsを次のように書き変えたところ無事レンダリングまではされるようになりました。
(初期値に{}を入れた)

trainingRecords

1const [ trainingRecords, setTrainingRecords ] = useState([{}]);

しかし、console.log(trainingRecords)でみてみると、
最初に「+」ボタンを押すと空のオブジェクトが作られて、
二度目で初めて入力内容が配列に追加されていることがわかりました。
イメージ説明
最初の空のオブジェクトは不要なので作りたくないのですが、どう書けばいいでしょうか。

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

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

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

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

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

guest

回答2

0

自己解決

TypeScript

1interface TrainingRecord { 2 trainingName: string; 3 trainingWeight: string; 4 trainingReps: string; 5}

でtrainingRecordオブジェクトの型を宣言し、

TypeScript

1 const [ trainingRecord, setTrainingRecord ] = useState<TrainingRecord>({ 2 trainingName: "", 3 trainingWeight: "none", 4 trainingReps: "0", 5 }) 6 const [ trainingRecords, setTrainingRecords ] = useState<TrainingRecord[]>([]);

trainingRecord の型は TrainingRecord 型のオブジェクト(<TrainingRecord>
trainingRecords の型は TrainingRecord 型のオブジェクトの配列(<TrainingRecord[]>)を適用しました(参考)。

また今回、setStateした直後の配列をconsole.logで出力しようとしていたのですが、
こちらのQiitaの記事に「setState()は、引数にオブジェクトが渡された場合に、stateを即時にアップデートすることを保証しない」と書かれているように、うまくいかないこともあるようです。

投稿2021/02/24 03:59

moyong

総合スコア19

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

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

0

配列でないといけないようなので、最初だけは

if (!trainingRecords.length) { setTrainingRecords([trainingRecord]); } else { ...

にしてはいかがでしょう?

投稿2021/02/23 11:11

編集2021/02/23 11:11
siruku6

総合スコア1382

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

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

siruku6

2021/02/23 11:18

(もしこれでよいのだとすると、else文の方もエラーが出そうな気がしますが...)
moyong

2021/02/23 11:46

回答ありがとうございます。 本文の中で返信させていただきましたm(__)m
siruku6

2021/02/23 12:19 編集

useStateもtypescriptも使用していないので、これ以上はお役に立てなさそうです... 他の方に期待します。 少なくとも、ここに掲載しているソースコード以外の部分に問題がある可能性があるように見えるので、とりあえず関連する他のソースも掲載しておいた方がいいかと思います。 `never`なんちゃらという型になる原因にも問題があるかもしれませんし、全くそれとは関係ないところかもしれません
moyong

2021/02/24 03:51

解決しました! >>`never`なんちゃらという型になる原因にも問題があるかもしれません trainingRecords配列に対して型を宣言していなかったため、neverとでてしまっていたようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問