# State

## Single State Tree

単一の state 用 tree

Vuex は single state tree を用います。つまり、この単一のオブジェクトに、アプリケーションの全てのレベルの state を持たせ、そしてこのオブジェクトが "single source of truth" としての役割を与えます。(訳注: 大げさな言い回しだが、単にこのオブジェクトを参照すれば全てがわかりますよ、という状態にしておきますよ、ということ。)  ですので、通常であれば各 App には、一つだけの store を用いるということです。single state tree になっていることによって、state の各部分がツリーのどの部分なのかということが容易にわかりますし、デバッグのために現在の App の状態のスナップショットを取るのも簡単です。

single state tree と、modularity (分割運用可能性) とは相反するものではありません。おって state と mutations を sub module へと分割していく手法についても説明します。

### Getting Vuex State into Vue Components

Vuex の state を Vue Component に注入する

では store の中の state を Vue Component の中で表示するにはどうしたらいいでしょうか。Vuex の store は reactive なので、state を「読みだす」一番簡単な方法は computed property の中で store の state を return することです。

```javascript
// let's create a Counter component
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}
```

store.state.count が変更されるたびに、computed property が再評価されますので、結果としてこれが関連づけられている DOM が更新されます。

しかし上記のようなコードを書いてしまうと、グローバルにある store という変数を用いているので、モジュール化したコンポーネントの中で store を使おうとすると、全てのコンポーネントの中で store を import しなくてはいけなくなります。またコンポーネントのテストをする際にも、mock が必要になってしまいます。(訳注: const store = Vuex.store() と store を作ったファイルの中では store にアクセスできるが、別ファイルに切り出した component でこれを使おうと思ったら、store を import しなくてはいけない。これは現実的ではないし、面倒だ。ということ。)

そこで、Vuex は store を子 component に「注入(inject)」する機構を用意しています。ルートコンポーネントに store オプションを与えることでこれを実施できます。(ただし Vue.use(Vuex) を行っておいてください)

```javascript
const app = new Vue({
  el: '#app',
  // provide the store using the "store" option.
  // this will inject the store instance to all child components.
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})
```

(訳注: store: store, としなくてもいいのは新しいシンタックス)

ルートインスタンスに store オプションを与えることで、子コンポーネント全てに store が注入されます。そして各コンポーネント内で this.$store という形でアクセスできるようになります。では、さっそく Counter が store をこの手法に使えるように書き換えてみましょう。

### MapState ヘルパー

component が複数の store state を使う場合に、なんども computed properties の中で宣言するのは冗長です。そういう場合には mapState を用いてください。これによって getter function を作ることができます。

```javascript
// in full builds helpers are exposed as Vuex.mapState
import { mapState } from 'vuex'

export default {
  // ...
  computed: mapState({
    // arrow functions can make the code very succinct!
    count: state => state.count,

    // passing the string value 'count' is same as `state => state.count`
    countAlias: 'count',

    // to access local state with `this`, a normal function must be used
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}
```

mapState に文字列の配列を渡すこともできます。ただし、mapped computed property の名前と state の sub tree の名前が同じ場合だけ、このように書くことができます。

```javascript
computed: mapState([
  // map this.count to store.state.count
  'count'
])
```

### Object Spread Operator

mapState は object を返します。では、他の local computed property とこの mapState で返されたオブジェクトを computed プロパティの中で組み合わせて使うには、どうしたらいいのでしょうか？ 通常であれば複数のオブジェクトを一つにまとめる何かを使って、それでできたオブジェクトを computed プロパティに渡せばいいわけです。一番簡単なのは、object spread operator  を使うことです。

```javascript
computed: {
  localComputed () { /* ... */ },
  // mix this into the outer object with the object spread operator
  ...mapState({
    // ...
  })
}
```

### Components Can Still Have Local State

local の state を持ってもよい

Vuex は全ての state を Vuex の中で管理するように、と強制しているわけではありません。もちろんより多くの state を Vuex で管理した方が、state の変更は明示的になりデバッグも簡単になります。とはいえ、時には煩雑で直感的でなくなってしまう場合もあります。もし state が単一のコンポーネントしか紐づいていないのであれば、それはローカルステイトとして切り離してしまった方がいいでしょう。常にこのトレードオフを判断し、アプリケーションに応じた手法を選択する必要があります。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://super-yusuke.gitbook.io/udemy-vue-basic/vuex-de-state-wosuru/core-concepts/state.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
