programing

비동기 API 호출 후 vuex getter를 사용하는 방법

prostudy 2022. 6. 6. 10:34
반응형

비동기 API 호출 후 vuex getter를 사용하는 방법

상태를 변환한 비동기 작업을 디스패치한 후 vuex에서 getter를 호출하는 적절한 방법은 무엇입니까?

나는 내가 의미하는 바를 설명하기 위해 예시 스니펫을 만들었다.당신이 볼 수 있듯이.getLastNameByName()에러가 발생하다state.persons비어 있습니다.이상한 건, 제가 인쇄를 하면state.persons이 getter에서는 api 호출 후에 어레이가 출력합니다.

예상되는 동작은 다음과 같습니다.getLastNameByName('John')돌아온다{name: 'John', lastname: 'Smith'}

const store = new Vuex.Store({
  state: {
    persons: []
  },

  getters: {
    getLastNameByName: (state) => (name) => {

      // console.log(state.persons) returns the state, yet I cannot call .find on it 
      return state.persons.find(element => {
        return element.name === name
      }).lastname
    },
  },

  mutations: {
    setPersons: (state, payload) => {
      state.persons = [...payload]
    }
  },

  actions: {
    async getPeople({commit}) {
        return new Promise(function(resolve, reject) {
          setTimeout(async () => {
             commit('setPersons', [{
               name: 'John',
               lastname: 'Smith'
            }, {
            name: 'Sarah',
            account: 'Appleseed'
          }])

           resolve();
         }, 1000)
      })
  }
  }
})

new Vue({
  store,
  el: '#app',
  mounted() {
    this.$store.dispatch('getPeople').then( () =>  { 
      console.log(this.$store.getters.getLastNameByName('John'))
    })
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
</div>

set Timeout()은 대기 가능한 개체를 반환하지 않습니다.약속 확인:

const store = new Vuex.Store({
  state: {
    persons: []
  },

  getters: {
    getLastNameByName: (state) => (name) => {
      return state.persons.find(element => {
        return element.name === name
      }).lastname
    },
  },

  mutations: {
    setPersons: (state, payload) => {
      state.persons = [...payload]
    }
  },

  actions: {
    async getPeople({commit}) {
        return new Promise(function(resolve, reject) {
          setTimeout(async () => {
             commit('setPersons', [{
               name: 'John',
               lastname: 'Smith'
            }, {
            name: 'Sarah',
            account: 'Appleseed'
          }])

           resolve();
         }, 1000)
      })
    }
  }
})

new Vue({
  store,
  el: '#app',
  mounted() {
    this.$store.dispatch('getPeople').then(() => {
       console.log(this.$store.getters.getLastNameByName('John'));
    })
  } 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
</div>

어쨌든 비동기 호출을 직접 저장하는 것은 적절한 방법이 아닙니다.이 경우 더 나은 해결책은watch저장 상태 또는 사용computed특성.

jsbin.com에서 시험해 봤지만 개선은 거의 없고 문제 없음:

<!DOCTYPE html>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Vue example</title>

<div id="app">
  <show-person
    :name="getLastName('John')"
  ></show-person>
</div>

<script src="https://unpkg.com/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.min.js"></script>

<script>
const store = new Vuex.Store({
  state: {
    persons: []
  },

  getters: {
    getLastName: state => name => {
      return state.persons.length
        ? state.persons.find(element => {
            return element.name === name
          }).lastname
        : ''
    }
  },

  mutations: {
    setPersons: (state, payload) => {
      state.persons = [...payload]
    }
  },

  actions: {
    getPeople: ({ commit }) => new Promise(res => {
      const data = [
        {name: 'John', lastname: 'Smith'},
        {name: 'Sarah', account: 'Appleseed'}
      ]
      setTimeout(() => {
        commit('setPersons', data)
        res()
      }, 1000)
    })
  }
})

const ShowPerson = {
  functional: true,
  render: (h, ctx) => h('p', ctx.props.name)
}

new Vue({
  store,
  el: '#app',

  components: {
    ShowPerson
  },

  computed: {
    ...Vuex.mapGetters([
      'getLastName'
    ])
  },

  methods: {
    ...Vuex.mapActions([
      'getPeople'
    ])
  },

  created () {
    this.getPeople()
  }
})
</script>

언급URL : https://stackoverflow.com/questions/53777258/how-to-use-vuex-getter-after-async-api-call

반응형