I'm trying to create a listenAuth function that watches "onAuthStateChanged" in firebase to notify the vuex store when a user has logged in or out. As far as I can tell, I'm only modifying state.authData using the mutation handler, unless I'm missing something?
I'm getting the error:
[vuex] Do not mutate vuex store state outside mutation handlers.
Here's my App.vue javascript (from my component)
<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>
Here's my action (changeAuth) function
export const changeAuth = ({ dispatch, state }, authData) => {
dispatch(types.AUTH_CHANGED, authData)
}
Here's my store (the parts that matter)
const mutations = {
AUTH_CHANGED (state, authData) {
state.authData = authData
}
}
const state = {
authData: {}
}
After struggling with the same problem, I found that the error only happens when we try to store the auth/user data in the Vuex state.
Changing from...
const mutations = {
AUTH_CHANGED (state, authData) {
state.authData = authData
}
}
...to...
const mutations = {
AUTH_CHANGED (state, authData) {
state.authData = JSON.parse(JSON.stringify(authData))
}
}
would solve your case.
I also came across this issue. My store:
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}))
}
}
Fixed it by replace state.items = payload.items
with:
state.items = payload.items.slice()
The reason is that arrays are stored as references in Javascript and
payload.items
is likely to be changed outside Vuex. So we should just use a fresh copy ofpayload.items
instead.
For state objects, use:
state.someObj = Object.assign({}, payload.someObj)
And don't use JSON.parse(JSON.stringify(someObj))
as it's much slower.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With