[Firebase] onShapshot을 사용해서 Vuex한테 욕을 먹으면...

개시하다


Firebase 방법onSnapshotVuex을 사용할 때 이런 오류가 발생했습니다.
Error: [vuex] do not mutate vuex store state outside mutation handlers.
state는 분명히 변경되지 않았는데...많은 사람들이 그렇게 말하겠지.
이번에는 이 이유와 대응법에 대한 보도다.

우선, 실제 인코딩은 여기에 있다


이번에는 snapshot으로 복선상자가 있는 ToDo 목록을 실시간으로 업데이트하는 프로젝트를 만들었습니다.
index.vue
<template>
  <div>
    <div v-for="(item, index) in taskList" :key="index">
      <input
        type="checkbox"
        :checked="item.isChecked"
        @click="toggleCheck(item.isChecked, item.id)"
      >
    </div>
  </div>
</template>

<script>
export default {
  ...mapState({
    taskList: state => state.taskList
  })
  created() {
    this.$store.dispatch('task/fetchTaskList')
  }
  methods: {
    toggleCheck(isChecked, taskId){
      this.$store.dispatch('task/toggleCheck', { isChecked: isChecked, taskId: taskId })
    }
  }
}
</script>
store/task.js
export const state = () => ({
  taskList: []
})

export const mutations = {
  setTaskList(state, list) {
    state.taskList = list
  }
}

export const actions = {
  fetchTaskList({ commit, rootState }) {
    const taskList = []
    this.$firestore()
      .collection('user')
      .doc(rootState.sign.uid)
      .collection('taskList')
      .onSnapshot(async querySnapshot => {
        await querySnapshot.forEach(doc => {
          const task = Object.assign(doc.data(), { id: doc.id })
          taskList.push(task)
        })
        commit('setTaskList', taskList)
      })
  }
}
간단하게 말하자면, 단지 snapshot을 통해 목록을 얻어서 표시할 뿐이다.
여기까지는 문제 없이 돌아가고 있다.
여기에 작업 검사 처리를 추가해 보십시오.
store/task.js
async toggleDone({ rootState }, { isDone, taskId }) {
    const newTask = {
      isDone: isDone ? false : true
    }
    await this.$firestore()
      .collection('user')
      .doc(rootState.sign.uid)
      .collection('taskList')
      .doc(taskId)
      .set(newTask, { merge: true })
  }
}
이 확인란을 누르면 오류가 발생합니다.
Error: [vuex] do not mutate vuex store state outside mutation handlers.
state는 변경이 없을 거예요. 왜요?

자세한 오류 상태

  • 방금 오류가 발생한 상태에서 재부팅을 시도합니다.
  • 검사의 상태는 문제없이 반영된다.
  • 목록의 재취득은 검사의 업데이트 처리가 아니라는 것을 알 수 있습니다.
  • 목록을 가져오는 함수에 컨트롤러를 보내서 어디에 멈추었는지 확인합니다.
  • 검사의 값을 업데이트했을 때onSnapshot 이후만 처리한다고 판명했다.

  • store/task.js
    export const actions = {
      fetchTaskList({ commit, rootState }) {
        const taskList = []
        this.$firestore()
          .collection('user')
          .doc(rootState.sign.uid)
          .collection('taskList')
    // firestoreの値が更新された際、ここから下の処理が自動で動く
          .onSnapshot(async querySnapshot => {
            await querySnapshot.forEach(doc => {
              const task = Object.assign(doc.data(), { id: doc.id })
              taskList.push(task)
            })
            commit('setTaskList', taskList)
          })
      }
    }
    
    onSnapshot 마이그레이션 처리만 수행하면 taskList.push(task) 어떻게 수행합니까?
    그러니까 범인이 이 놈이라는 거야.
    const taskList = []
    

    고찰하다.


    두 번째 자동 취득 때는 새로운 타스크리스트가 존재하지 않았고, state의 타스크리스트를 봤잖아요.이 처리는 actions에서 이루어졌기 때문에 잘못된 내용과 같이 mutations 이외의 state의 값이 변경되었습니다???

    결론


    이렇게 하시면 됩니다.
    store/task.js
    export const actions = {
      fetchTaskList({ commit, rootState }) {
        this.$firestore()
          .collection('user')
          .doc(rootState.sign.uid)
          .collection('taskList')
    // firestoreの値が更新された際、ここから下の処理が自動で動く
          .onSnapshot(async querySnapshot => {
            const taskList = []
            await querySnapshot.forEach(doc => {
              const task = Object.assign(doc.data(), { id: doc.id })
              taskList.push(task)
            })
            commit('setTaskList', taskList)
          })
      }
    }
    
    taskList의 정의를 onSnapshot에 넣으면 정상적으로 작동합니다.

    말하자면...


    원래 함수에 정의된 변수명과 state에 사용된 변수명은 오류가 증가할 뿐이므로 이렇게 하지 않는 것이 좋습니다.
    함수에 사용할 변수 이름을 스스로 준비하는 것이 가장 좋다.

    좋은 웹페이지 즐겨찾기