Vuexのモジュール間で非同期処理を伴う実装をしていた際に「TypeError: Cannot read properties of undefined (reading ‘someProperty’)」というエラーでハマったので、備忘録として解決方法を記録します。
目次
この記事でわかること
- Vuexのモジュール間通信でTypeErrorが発生するメカニズム
- 非同期処理(Async/Await)を用いた正しいActionの書き方
- 依存関係のあるモジュール間で安全にStateを更新する手順
[現象] 非同期Action内で発生するundefinedエラー
APIリクエストなどの非同期処理を伴うVuex Actionにおいて、別のモジュールの値を参照しようとした瞬間にエラーが発生するパターンです。コード上は問題なさそうに見えても、実行時に以下のメッセージが表示されます。
TypeError: Cannot read properties of undefined (reading 'someProperty')[環境] 発生しやすい環境
- Vue.js 2 / 3
- Vuex (モジュール分割を行っている場合)
- Nuxt.js プロジェクト
[原因] モジュール間の更新タイミングの不整合
原因は、非同期処理が完了してStateが更新される前に、依存する次の処理(ミューテーションやアクション)が実行されてしまうことにあります。特にモジュールを跨いで rootState を参照している場合、対象のモジュールがまだ初期値(undefinedやnull)の状態でアクセスしようとしてエラーになります。
[解決策] Async/Awaitの徹底とDispatchの活用
解決の鍵は、await を使って非同期処理の完了を厳密に待機すること、そして他モジュールの状態更新を dispatch 経由で待ち受けることです。
修正後のアクション記述例
// store/item.js
actions: {
async updateItem({ commit, rootState, dispatch }) {
// 1. 自モジュールの非同期処理を待つ
const data = await fetch('/api/item').then(res => res.json());
commit('SET_ITEM', data);
// 2. 他モジュールのState更新をdispatchで呼び出し、その完了を待つ
// { root: true } オプションが必要
await dispatch('otherModule/ensureValueIsSet', null, { root: true });
// 3. 他モジュールの値が確定したことを確認してミューテーションを実行
if (rootState.otherModule && rootState.otherModule.someValue) {
commit('UPDATE_DEPENDENCY', rootState.otherModule.someValue);
}
}
}まとめ
VuexでのTypeErrorは、非同期処理の「待ち」が不足していることが主な原因です。以下のポイントを再確認しましょう。
| 確認項目 | 推奨される対応 |
|---|---|
| 非同期API呼び出し | 必ず await でレスポンスを待つ |
| 他モジュールの更新 | dispatch のPromiseを await する |
| rootStateの参照 | 参照前にオブジェクトの存在チェックを入れる |
モジュール間通信が複雑になる場合は、Actionの実行順序を整理することで、不意なTypeErrorを防ぐことができます。


