programing

mapstate의 데이터가 로드를 마칠 때까지 기다립니다.

javaba 2023. 1. 29. 20:22
반응형

mapstate의 데이터가 로드를 마칠 때까지 기다립니다.

저장했습니다.userProfileVuex제 프로젝트 전체를 통해 접근할 수 있게 되었습니다.하지만 만약 내가 그것을 사용하고 싶다면created()훅, 프로파일이 아직 로드되지 않았습니다.개체가 존재하지만 저장된 데이터가 없습니다.적어도 페이지의 초기 로드에서.나중에 (버튼을 클릭하는 등) 접속하면 모든 것이 정상적으로 동작합니다.데이터 로딩이 완료될 때까지 기다릴 수 있는 방법이 있나요?

방법은 다음과 같습니다userProfile로 설정되어 있다.Vuex:

mutations: {
    setUserProfile(state, val){
      state.userProfile = val
    }
},
actions: {
    async fetchUserProfile({ commit }, user) {
      // fetch user profile
      const userProfile = await fb.teachersCollection.doc(user.uid).get()
  
      // set user profile in state
      commit('setUserProfile', userProfile.data())
    },
}

액세스 하고 싶은 코드는 다음과 같습니다.

<template>
<div>
  <h1>Test</h1>
  {{userProfile.firstname}}
  {{institute}}
</div>
</template>


<script>
import {mapState} from 'vuex';

export default {
  data() {
    return {
      institute: "",
    }
  },
  computed: {
      ...mapState(['userProfile']),
  },
  created(){
    this.getInstitute();
  },

  methods: {
    async getInstitute() {
      console.log(this.userProfile); //is here still empty at initial page load

      const institueDoc = await this.userProfile.institute.get();
      if (institueDoc.exists) {
        this.institute = institueDoc.name;
      } else {
        console.log('dosnt exists') 
      }
      
    }
  }
}
</script>

콘솔 로그인을 통해 코드 실행 순서에 문제가 있음을 알게 되었습니다.첫 번째 방법은getInstitute실행되면,action그 다음에mutation. 를 추가하려고 했습니다.loaded매개 변수와 함께 재생되었습니다.await이 문제를 해결하려고 했지만 효과가 없었습니다.

당신이 만든다고 해도created또는mounted비동기에서는 컴포넌트의 렌더링이 지연되지 않습니다.그 후 배치된 코드의 실행이 지연될 뿐입니다.await.

템플릿의 일부(또는 전체)를 렌더링하지 않는 경우userProfile가 있다id(또는 사용자가 가지고 있는 기타 속성), 단순히v-if

<template v-if="userProfile.id">
  <!-- your normal html here... -->
</template>
<template v-else>
   loading user profile...
</template>

코드를 실행하려면userProfile내부 속성 중 하나에 워처를 배치할 수 있습니다.이 경우는, 다음과 같이 동작합니다.

export default {
  data: () => ({
    institute: ''
  }),
  computed: {
    ...mapState(['userProfile']),
  },
  watch: {
    'userProfile.institute': {
      async handler(institute) {
        if (institute) {
          const { name } = await institute.get();
          if (name) {
            this.institute = name;
          }
        } 
      },
      immediate: true
    }
  }
}

사이드 노트:Vue 3에는 이 패턴을 위한 서스펜스라고 하는 내장 솔루션이 포함되어 있습니다.안타깝게도, 몇 군데만 언급되어 있고, 제대로 문서화되어 있지 않으며, API가 변경될 조짐이 있습니다.
그러나 렌더링 조건이 부모로부터 완전히 분리될 수 있기 때문에 매우 훌륭합니다.그것은 매달 수 있는 아이 안에 들어 있을 수 있다.아이가 선언하는 유일한 것은 "현재 로드 중" 또는 "로드 완료"입니다.모든 서스펜션이 준비되면 템플릿 기본값이 렌더링됩니다.
또한 자녀가 동적으로 생성되고 새 자녀가 푸시되면 부모 서스펜스는 새로 추가된 자녀가 로드될 때까지 폴백(로드) 템플릿으로 다시 전환됩니다.이 작업은 개봉 즉시 완료되며, 신고만 하면 됩니다.mounted비동기입니다.
한마디로 Vue 2에서 기대했던 것.

언급URL : https://stackoverflow.com/questions/66090897/wait-for-data-in-mapstate-to-finish-loading

반응형