Closed7

AmplifyのDataStore(js)のハマリどころ

ハトすけハトすけ

リレーションは慎重に

AmplifyのDataStoreはリレーションの親が削除されると、子もカスケード削除される。
1対1などは、リレーションのどちらにつけてもよいように感じるかもしれないが、間違って本来の子側にいなるべき方につけてしまうと、消えてほしくないデータが消えてしまう。
https://docs.amplify.aws/lib/datastore/relational/q/platform/js/

ハトすけハトすけ

DataStoreの初期クラウド同期終わる前にDataStore.queryすると空のデータしか入っていない。

これはDataStoreのクエリが以下のような仕様だから。

  • DataStoreは初期化時にクラウド同期を行い、ローカルのIndexDBと同期させる。
  • DataStoreのクエリはローカルのindexDBに対して行われる。
  • アプリを初めてそのブラウザで使った場合、クラウド同期が終わるまで、indexDBが空になる。
  • あるページを表示する際に、useEffectでDataStoreのクエリを叩くが、クラウド同期が終わっていないばあ、nullになってしまう。

コレに対応するためには2通りの方法があるとされるが、実践的に、つかえるのはほぼ一つ。

  • イベントリスナーでDataStoreがreadyになってから、クエリを叩く
  • DataStore.queryの代わりにDataStore.obserbeQueryを使う

1つ目の方法は、reactのライフサイクルとDataStoreのライフサイクルが一致しないので、うまくいかなくなるときがちょこちょこでてきた。
2つめの方法は、初回がnullでも同期がおわればsubscribeが発火するので、うまくいく。

  useEffect(() => {
    if (!corporationId) return;

    const sub = DataStore.observeQuery(Corporation, (c) =>
      c.id.eq(corporationId)
    ).subscribe(({ items }) => {
      setCorporation(items[0] ?? null);
    });

   // NOTE: return  sub.unsubscribeとするとうまくいかない
    return () => sub.unsubscribe();
  }, [corporationId]);
ハトすけハトすけ

useEffectのreturnにunsubscribeを渡すとき、直接関数を渡してはいけない

good
  useEffect(() => {
    if (!corporationId) return;

    const sub = DataStore.observeQuery(Corporation, (c) =>
      c.id.eq(corporationId)
    ).subscribe(({ items }) => {
      setCorporation(items[0] ?? null);
    });

    // ⚠ここに注意
    return () => sub.unsubscribe();
  }, [corporationId]);
bad
  useEffect(() => {
    if (!corporationId) return;

    const sub = DataStore.observeQuery(Corporation, (c) =>
      c.id.eq(corporationId)
    ).subscribe(({ items }) => {
      setCorporation(items[0] ?? null);
    });

    // ⚠ここに注意
    return sub.unsubscribe;
  }, [corporationId]);

以下のようなエラーが発生する。

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading ‘_state’)
ハトすけハトすけ

DataをAmplifyStudioで定義するさいに、CustomTypeに!IDをつけるとよくわからないことになる

クラスを生成する際に、TypeScriptの型エラーにひっかかる。

ハトすけハトすけ

DataをAmplifyStudioで定義するさいに、CustomTypeでidという名前のキーをつかうとよくわからないことになる。

CustomTypeではidという名前ではないものを使いましょう。

このスクラップは2023/10/30にクローズされました