Vue

[Solved] [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined

moyanglee 2022. 8. 26. 10:30

정상적으로 작동은 하지만, 콘솔창에
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'length')
라는 에러가 발생하였다. 

어떻게 해결 할 수 있었는지 알아보자.

 

Problem

위 에러가 의미하는 바는 명확하다. 화면을 렌더하려고 하는데 undefined, 즉 아직 정의되지 않은 속성을 읽으려고 하고 있다는 뜻이다. 

 

아래의 간단한 예시 코드를 통해 알아보자.

아래의 코드를 처음 렌더할 때 info.someProperty는 아직 undefined된 상태 이므로, 에러가 발생하게 될 것이다.

<span>
{{info.someProperty}}
</span>

////////.../////
data(){
	return {
    	info: {}
    }
}

async mounted(){
	await getSomeProperty() //info에 someProperty를 넣어주는 함수
}


근데 왜 작동은 정상적으로 하는 걸까?

 

이는 아래의 순서로 작동하고 있기 때문이다. 

1. 화면을 렌더( 이때 해당 property는 undefined 일 것이다.)

2. 해당 property의 값이 정의된다. 

3. 정의된 property가 화면에 정상 출력된다. 

 

Solution

어떻게 해결 할 수 있을까?

이 문제는 3가지 방법으로 해결 할 수 있다. (각자 알맞은 방법을 사용하자.)

참고로 나는 3번 방식을 추천하고, 해당 방식으로 해결했다.

 

1. 렌더 전 속성을 명시적으로 정의 해주기

위에 에러가 발생하던 코드를 아래처럼 someProperty라는 속성을 명시적으로 정의해주는 방식으로 변경해주면 에러는 더이상 발생하지 않는다.

<span>
{{info.someProperty}}
</span>

////////.../////
data(){
	return {
    	info: {someProperty: {}}
    }
}

async mounted(){
	await getSomeProperty() //info에 someProperty를 넣어주는 함수
}

 

2. v-if 

혹은, 아래처럼 렌더 되는 부분에 v-if 조건문을 활용하는 방식으로 해결 할 수도 있다.

<span v-if="info.someProperty">
{{info.someProperty}}
</span>

////////.../////
data(){
	return {
    	info: {}
    }
}

async mounted(){
	await getSomeProperty() //info에 someProperty를 넣어주는 함수
}

 

3. Optional Chaining

가장 추천 하고 싶은 방법은 3번 방법이다.

나의 경우, 아래 부분을 렌더하면서 생긴 에러였다.

     <table v-if="infoDetail.result.length > 0">
     ...
     </table>

 

 

infoDetail 이라는 값을 받아와서, 그 안에 있는 result의 길이에 따라 조건부 렌더를 하려고 했는데, 
아직 데이터를 받아오기전에, 즉 result가 undefined된 상태에서 .length 를 읽으려고 하니 에러가 발생하였다. 
이 부분을 optional chaining을 통해 조건부 렌더를 하니 좀 더 예쁘게 에러를 처리 할 수 있었다.

            <table
              v-if="
                info.result &&
                info.result.length > 0
              "
            >
            ...
            </table>