# state vs data

Vue.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ data ์†์„ฑ๊ณผ ๋ทฐ์—‘์Šค(Vuex)์˜ state ์†์„ฑ ์ค‘ ์–ด๋–ค ๊ฑธ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ณ ๋ฏผํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์†์„ฑ์˜ ์ •์˜์™€ ์–ด๋–ค ์ƒํ™ฉ์—์„œ ๋ทฐ์—‘์Šค์˜ state๋ฅผ ์“ฐ๋ฉด ์ข‹์€์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

# data ์†์„ฑ

data ์†์„ฑ์€ ๋ทฐ์˜ ๋ฐ˜์‘์„ฑ(Reactivity)์ด ์ฃผ์ž…๋œ ์†์„ฑ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ์˜ ๊ฐ’์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค.

<template>
  <div>{{ message }}</div> <!-- Hello Vue.js -->
</template>
new Vue({
  data: {
    message: 'Hello Vue.js'
  }
})

๋ฐ˜์‘์„ฑ์ด ์ฃผ์ž…๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ๊ฐ’์ด ๋ณ€ํ•˜๋ฉด ํ™”๋ฉด์ด ๋‹ค์‹œ ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.

<template>
  <div>{{ message }}</div> <!-- changeMessage() ๊ฐ€ ์‹คํ–‰๋˜๋ฉด hi ํ‘œ์‹œ -->
</template>
new Vue({
  data: {
    message: 'Hello Vue.js'
  },
  methods: {
    changeMessage() {
      this.message = 'hi';
    }
  }
})

# state ์†์„ฑ

state ์†์„ฑ๋„ ๋ทฐ์˜ ๋ฐ˜์‘์„ฑ์ด ์ฃผ์ž…๋˜์–ด ์žˆ๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์Šคํ† ์–ด์— ์ •์˜ํ•˜๊ณ  ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<div>{{ $store.state.message }}</div>
new Vuex.Store({
  state: {
    message: 'Hello Vue.js'
  }
})

# ์ ‘๊ทผ ๊ฐ€๋Šฅ ๋ฒ”์œ„

data ์†์„ฑ์€ ํ•ด๋‹น ์†์„ฑ์„ ์„ ์–ธํ•œ ํŠน์ • ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น data ์†์„ฑ์„ ์ ‘๊ทผํ•˜๋ ค๋ฉด ํ”„๋กญ์Šค ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์—, state ์†์„ฑ์€ ์Šคํ† ์–ด์— ํ•œ๋ฒˆ ์ •์˜ํ•˜๋ฉด ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๊ฐ’ ๋ณ€๊ฒฝ ๋ฐฉ์‹

data ์†์„ฑ์€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋‚˜ ๋ผ์ดํ”„์‚ฌ์ดํด ํ›… ํ•จ์ˆ˜ ๋“ฑ ์•„๋ž˜์™€ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ this๋กœ ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

<template>
  <div>{{ count }}</div>
  <button @click="increment">+</button>
</template>
new Vue({
  data: {
    count: 0
  },
  methods: {
    increment() {
      this.count += 1;
    }
  }
})

state ์†์„ฑ์€ ๋ฎคํ…Œ์ด์…˜์œผ๋กœ๋งŒ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฎคํ…Œ์ด์…˜์„ ํ†ตํ•ด ๋ณ€๊ฒฝ๋œ ๊ฐ’์€ ํ•ด๋‹น state ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ๋ฐ˜์˜๋˜์–ด ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

<template>
  <div>{{ $store.state.count }}</div>
  <button @click="increase">+</button>
</template>
// count.vue
new Vue({
  methods: {
    increase() {
      this.$store.commit('increment');
    }
  }
})
// store.js
new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count += 1;
    }
  }
})

# Vuex๋ฅผ ์–ธ์ œ ์‚ฌ์šฉํ• ๊นŒ?

๋ทฐ์—‘์Šค๋Š” ๊ผญ ๋ทฐ์—‘์Šค๋ฅผ ์จ์•ผ๋งŒ ํŠน์ • ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ๋•Œ๋Š” state ์†์„ฑ์„ ์“ฐ๋Š” ๊ฒƒ์ด ํ”„๋กญ์Šค ์†์„ฑ๊ณผ ์ด๋ฒคํŠธ ์—๋ฐ‹ ๋ฐฉ์‹์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํŽธํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜์˜ ๊ณต๊ฐ„(์Šคํ† ์–ด)์— ๋ฐ€์ง‘๋˜๋Š” ๊ฒฝ์šฐ ์ดํ›„์— ํ•ด๋‹น ๊ณต๊ฐ„์ด ๋” ๋ณต์žกํ•ด์ง€๋Š” ๋ฌธ์ œ์ ์ด ์ƒ๊น๋‹ˆ๋‹ค. ๋˜ํ•œ, ํŠน์ • UI ์˜์—ญ์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ตœ๋Œ€ํ•œ ๊ทธ UI ์˜์—ญ์— ๊ฐ€๊นŒ์ด ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์ถ”ํ›„ ๊ธฐ๋Šฅ ํ™•์žฅ์ด๋‚˜ ์˜ค๋ฅ˜ ๋ถ„์„์—๋„ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

๋ทฐ์—‘์Šค๋ฅผ ์–ธ์ œ ์จ์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ต์€ ์—†์Šต๋‹ˆ๋‹ค. ์Šค์Šค๋กœ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒ”์œ„๋ฅผ ๊ตฌ๋ถ„ ์ง“๊ณ  ์–ด๋–ค ๋ฐ์ดํ„ฐ(์ƒํƒœ)๋ฅผ ์–ด๋””์— ์„ ์–ธํ• ์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ๋ทฐ์—‘์Šค๋ฅผ ๋” ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กญ์Šค๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ ๋‚ด๋ฆฌ๊ณ  ์ด๋ฒคํŠธ๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ ์˜ฌ๋ ค์„œ ๋ฐ์ดํ„ฐ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ๋ทฐ์—‘์Šค๋ณด๋‹ค ๋” ํŽธํ•˜๋‹ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด์ด ๋Œ€ํ•œ ํŒ๋‹จ์€ ์—ฌ๋Ÿฌ๋ถ„๊ป˜ ๋งก๊ธฐ๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜ƒ