自己解決しました。
とりあえず、JSの操作ほど単純でエレガントではないですが以下の通りです。
まず下記のようなデータで試します。
JavaScript
1const object1 = { doc1: [{reply:'hello'} , {reply: 'hi jack'}] };
2const object2 = { doc2: [{reply:'greeting'} , {reply: 'hey'}] };
3//上記オブジェクトデータを、下記useStateの中に入れ、この質問の一番上に記載したようなデータ構造を作ります。
4const [objData, setObjData] = React.useState({...object2,...object3});
5
6//これは後から追加するオブジェクト
7const obj = {reply:'this is an added object'};
次に関数ですが、存在するkey (doccument id )ならば、そのキーとペアの配列にオブジェクトを挿入し、存在しないdocument id ならば新たなkey:valueを作成しその配列にオブジェクトを挿入します。
JavaScript
1
2 function addObjToData(documentId, newObj){
3 //もしドキュメントIDが存在するならば
4 if(objData[documentId] !== undefined){
5 //(prvData は元のデータ)
6 setObjData((prvData) => {
7 //関係ないデータは3ドット演算子でそのままにして、関係あるドキュメントの配列にnewObjを加える
8 return { ...prvData,
9 [documentId]:[...prvData[documentId], newObj]
10 }
11 })
12 }else{
13 setObjData((prvData) => {
14 //新たなドュメントであれば、元のデータは維持しつつ、別にドキュメントID:[配列オブジェクトを作成]
15 return {
16 ...prvData,
17 [documentId]:[newObj]
18 }
19 })
20 }
21 }
注意しなければならないのは[ ] が3つの意味合いで使われていること。
1つ目は配列のarray [ ]
2つ目はオブジェクトのキーを入れるためのobjData[key]。これで要素があるかどうか(キーが存在するか)を確認。
3つ目はオブジェクトのキーに対して好きな名前をつけるために、変数の代入を許容するための[ keyName ]: value
関数を使ってみると
JavaScript
1addObjToData('doc1', obj);
2//結果は
3// { doc1: [{reply:'hello'} , {reply: 'hi jack'}, {reply:'this is an added object'} ] ,
4// doc2: [{reply:'greeting'} , {reply: 'hey'}]
5//}
6
7
8// さらに続けて存在しないdocumentId で代入すると
9addObjToData('doc3', obj);
10
11// { doc1: [{reply:'hello'} , {reply: 'hi jack'}, {reply:'this is an added object'} ] ,
12// doc2: [{reply:'greeting'} , {reply: 'hey'}] ,
13// doc3: [{reply:'this is an added object'} ]
14//}
所望のドキュメントIDの配列内のreply: のデータを順に全て表示したい場合はこんな関数
JavaScript
1 function showObjReplyData(docId){
2 if(objData[docId] !== undefined){
3 objData[docId].map((data) => {
4 console.log('Show reply: ', data.reply);
5 })
6
7 }else{
8 console.log('No such document id');
9 }
10 }
また、スプレッド演算子とスライスを組み合わせれば、配列内の所望のオブジェクトの間に別のオブジェクトを入れたり、特定の位置のオブジェクトだけを消したりもできる。
例えば、既にある配列の2番目(index1)に新たオブジェクトを挿入する場合。
JavaScript
1{
2...prvData,
3 [documentId] : [...prvData[documentId].slice(0, 1), anotherObject, ...prvData[documentId].slice(1) ];
4}
また、オブジェクト内に特定のキーがあるかは以下の方法も使えます
JavaScript
1Object.keys(objData).includes(docmentId)
2// 上は objData[documentId] !== undefined と同じ
3
4//下記のようにラップしたり
5 function isObjKeyExist(stateData, key) {
6 if (Object.keys(stateData).includes(key)) {
7 return true;
8 } else {
9 return false;
10 }
11 }