programing

Vuex 및 VueJs(변환 핸들러 외부에 있는 vuex 스토어 상태를 변환하지 마십시오)

minecode 2022. 8. 13. 23:11
반응형

Vuex 및 VueJs(변환 핸들러 외부에 있는 vuex 스토어 상태를 변환하지 마십시오)

리슨(listen)을 작성하려고 합니다.파이어베이스에서 "onAuthStateChanged"를 감시하여 사용자가 로그인 또는 로그아웃했을 때 vuex 저장소에 통지하는 인증 함수입니다.내가 아는 한, 난 단지 상태를 바꾸는 것뿐이야.변환 핸들러를 사용하는 AuthData? 내가 놓친게 아니라면?

에러가 표시됩니다.

[vuex] Do not mutate vuex store state outside mutation handlers.

여기 내 앱이 있다.vue javascript (내 컴포넌트에서)

<script>
// import Navigation from './components/Navigation'
import * as actions from './vuex/actions'
import store from './vuex/store'
import firebase from 'firebase/app'

export default {
  store,
  ready: function () {
    this.listenAuth()
  },
  vuex: {
    actions,
    getters: {
      authData: state => state.authData,
      user: state => state.user
    }
  },
  components: {
    // Navigation
  },
  watch: {
    authData (val) {
      if (!val) {
        this.redirectLogin
        this.$route.router.go('/login')
      }
    }
  },
  methods: {
    listenAuth: function () {
      firebase.auth().onAuthStateChanged((authData) => {
        this.changeAuth(authData)
      })
    }
  }
}
</script>

다음은 내 액션(changeAuth) 함수입니다.

export const changeAuth = ({ dispatch, state }, authData) => {
  dispatch(types.AUTH_CHANGED, authData)
}

여기 제 가게가 있습니다(중요한 부품).

const mutations = {
  AUTH_CHANGED (state, authData) {
    state.authData = authData
  }
}

const state = {
  authData: {}
}

저도 이 문제를 발견했어요.내 가게:

  state: {
    items: []
  },
  mutations: {
    SetItems (state, payload) {
      // Warning
      state.items = payload.items
    }
  },
  actions: {
    FetchItems ({commit, state}, payload) {
      api.getItemsData(payload.sheetID)
        .then(items => commit('SetItems', {items}))
    }
  }

교체를 통해 수정state.items = payload.items포함:

state.items = payload.items.slice()

그 이유는 배열이 Javascript에 참조로 저장되기 때문입니다.payload.items는 Vuex 외부에서 변경될 수 있습니다.그래서 우리는 그냥 새로운 카피를 사용해야만payload.items대신.

상태 객체의 경우 다음을 사용합니다.

state.someObj = Object.assign({}, payload.someObj)

그리고 사용하지 마세요.JSON.parse(JSON.stringify(someObj))훨씬 느리니까.

같은 문제로 고민한 결과, 인증/사용자 데이터를 Vuex 상태로 저장하려고 할 때만 오류가 발생한다는 것을 알게 되었습니다.

변경처...

const mutations = {
  AUTH_CHANGED (state, authData) {
    state.authData = authData
  }
}

...에게...

const mutations = {
  AUTH_CHANGED (state, authData) {
    state.authData = JSON.parse(JSON.stringify(authData))
  }
}

네 사건을 해결할 수 있을 거야

저도 이 문제가 있어서 lodash를 사용하여 데이터를 복제했습니다.

state.someStatehere = $lodash.cloneDeep(data)

따라서 많은 답변에서 원인에 대해 동의할 수 있습니다. 즉, 상태에 저장된 객체는 해당 객체와 관련된 무언가에 의해 묵묵히 수정됩니다.그리고 많은 사람들이 그 물체를 복사하자고 제안합니다.

다른 방법은 오브젝트가 변경되는 동안 상태를 비우는 것입니다.이 기능은 어떤 이유로 개체를 복사할 수 없는 경우에 작동합니다.예를 들어 다음과 같습니다.

bla({ state } {}) {
  mutatingMethod(state.xxx);
},

아시면mutatingMethodxxx를 수정하고 있는 경우 다음과 같은 작업을 수행할 수 있습니다.

bla({ state } {}) {
  let xxx = state.xxx
  commit("SET_XXX", null)
  mutatingMethod(xxx);
  commit("SET_XXX", xxx)
},

이 문제를 해결하는 또 다른 방법은 다음과 같습니다(실제로 효과가 있었습니다).

auth()
  .onAuthStateChanged((user) => {
    if (user) {
      commit(MUTATION_TYPES.SET_USER, { ...user.toJSON() });
    }
  })

언급URL : https://stackoverflow.com/questions/38365075/vuex-vuejs-do-not-mutate-vuex-store-state-outside-mutation-handlers

반응형