Vue.js Vuex 흐름 순서 (freat.<Suspence>)

강정우·2023년 4월 12일
0

vue.js

목록 보기
46/72

우선 들어가기 앞서 vuex의 흐름 순서를 반드시 숙지하고 있어야한다

vuex 흐름 순서

  1. javascript 파일 => Actions,Mutations, Getters,State 접근 가능
    • router.js 참고 : store.getters["myStore/isLogin"]
  2. Vue Components => Actions 호출 (비동기일때) => Mutations호출 => State 조작
  3. Vue Components => Mutations호출 (동기일때) => State 조작
    • 뷰 콤포넌트에서 바로 뮤테이션 호출가능함.
  4. Vue Components => State 데이터읽기 OK
    • 이때 뷰 컴포넌트에서 mutation으로 임의로 변경하면 안 되는데 이는 그럼 vuex에서 변이관리 안 해주기 때문이다.
  • 그러면 이제 마주친 문제를 보자.

  • 이 원인을 조금 깔끔하게 정리해보자면

  • 최초에 마크업에 렌더링 되고 그 후 vuex의 async function들이 동작하면서 다시 렌더링을 하는데 이때 최초 마크업 렌더링시에 vuex의 속성값에 접근할 때 undefined혹은 null 이 뜨는 에러이다.
<template>
    <section v-for="result in results" :key="result">
        <div class="trBox2">
          ...
        </div>
        <div class="trView" v-if="result.view">
            <div class="tblGrid">
                <table>
                    <tr>
                        <td>
                          ...
                        </td>
                        <td style="padding-left:20px;width:20%;">
                            <div class="subTitle">수신처({{contactNum}})</div>
                            <div class="phoneList" style="height:130px;">
                                <ul>
                                    <li v-for="data in check_detailData" :key="data">{{data.phone}}  ({{data.result}})</li>
                                </ul>
                            </div>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    </section>
</template>
<script>
export default {
        contactNum() {
            return this.$store.getters['messages/getResultDetail'].length
        },
    },
}
</script>
  • 원인을 구글링하여 찾을 수 있었다.
Arguably, the error message could be improved on this one.

The error was caused by trying to iterate through a non-iterable (in your case undefined), using v-for.
Specifically, before the call made in mount() returns, product.
product_images is undefined, because you initiate product as empty object.
  • 내 상황에 맞춰 해석하자면 iterable하지 않는 객체를 .length를 통하여 접근하려했다는 것이 문제이다.
    즉, mount 되기 전에 접근하여 이땐 null이니까 문제가 됐다는 것이다.

  • 이를 해결하기 위해서는

  1. 안 멋진 방법
    • 그냥 v-if를 하여 해당 객체가 존재할 때 로직을 돌린다.
  2. 멋진 방법
    1) async setup()을 이용하여 문제의 해당 함수 작성
    2) <Suspence\> 컴포넌트를 이용하여 해당 컴포넌트를 집어 넣음

<Suspence>

parent doesn't need to know the actual condition(s) for which the markup is not yet to be rendered. 
It simply waits for all suspensible components to resolve.

In short, using <Suspense> you no longer need to hardcode the rendering logic into the template using 
v-ifs and specifying the condition in clear, on the wrapper. 

Each async child component contains its own condition and all it announces to the parent is: 
i'm done. When all are done, they're rendered.
  • 해당 컴포넌트는 부모의 마크업에서 자식 마크업이 렌더링되든 안 되든 일단 기다린다는 것이다.
    즉, <Suspence>를 사용하면 더 이상 렌더링 로직을 템플릿에 하드 코딩할 필요가 없다.
    v-ifs 및 wrapper에서 조건을 명확하게 지정하면 된다.

  • 각 비동기 자식 구성 요소에는 고유한 조건이 포함되어 있으며 부모에게 알림을 보내는 것은 다음과 같습니다
    내가 로직이 끝나고 모든 로직이 끝나면 그때 렌더링 해라~

즉, <Suspence>는 비동기 컴포넌트이다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글