모든 에러가 그렇겠지만 이번에 만난 에러도 상당한 답답함을 안겨줬다.
페이지에서 다른 페이지로 이동하여 특정 조건을 체크해서 충족되면 정상 이동하고 불충족되면 다시 이전 페이지로 Redirect하는 기능을 구현하는 중 만났다.
만들고 싶은 기능을 예를 들면 :
A페이지에서 B페이지로 router이동을 하는데 query정보가 없거나 잘못된 경우 A페이지로 Redirect하는 것 이다.
해당 기능을 구현하기 위해 라우터가드인 beforeRouteEnter()
를 사용하여 B페이지에 접근 시 제일 먼저 query
를 체크 한다.
query
조건이 만족되면 정상적으로 B페이지를 화면에 출력하고 불충족되면 next()
를 이용해 A페이지로 Redirect을 한다.
하지만 Redirect를 하게 될경우 오늘 주제인 에러를 뿜어 낸다.
구글 검색으로 알게된 사실은 "A페이지에서 B페이지로 갔다가 조건이 불충족 되어 B페이지에서 다시 A페이지로 이동할 경우 중복해서 Redirect를 한다"라는 의견이 많았다.
이게 머선말 이고?!
난 분명 B페이지에서 A페이지로 한번만 Redirect를 하는데 중복 이라니?!
"혹시 전역 라우터 가드(beforeEach
)를 사용하고 있어서 중복이라는 건가?"라고 생각해서 해당 부분을 주석 처리 후 테스트 해봤지만 동일한 에러가 발생 했다.
개답답... 이유를 알았는데 원인을 찾지 못하다니! 😤
다행히 몇번의 서치 끝에 해결책을 찾을 수 있었다. 하지만 정확한 원인은 모르겠다능.
Error 코드
<template>
<div>
<h1>A Page</h1>
<button @click="goToB">페이지이동</button>
</div>
</template>
<script>
export default {
methods:{
goToB() {
this.$router.push({name: 'bPage'});
},
}
}
</script>
👉 <button @click="goToB">페이지이동
- 버튼을 클릭하면
goToB()
가 실행
👉 this.$router.push({name: 'bPage'})
goToB()
내부 로직은router.push
를 통해bPage
로 이동
<template>
<div>
<h1>B Page</h1>
</div>
</template>
<script>
export default {
beforeRouteEnter(to, from, next){
next({name: 'aPage'});
},
}
</script>
👉 next({name: 'aPage'})
- component 라우터 가드(
beforeRouteEnter
)를 사용해서 B페이지로 접근한 경우 다시 A페이지로 Redirect한다. - 지금 예제는 Error를 재현하기 위해 바로 A페이지로 Redirect시키지만, 원래는 B페이지 접근 시 조건을 체크 해서 불충족 될 경우 Redirect한다.
위 예제로 코드를 실행하면 이번 주제인 Error가 발생한다.
분명 Redirect는 B페이지에서 A페이지로가는 한번 뿐인데 중복이라니?!
Error 해결책
Solution 1 : router-link 사용
<template>
<div>
<h1>A Page</h1>
<router-link :to="{name: 'bPage'}">페이지이동</router-link>
</div>
</template>
<script>
export default {
}
</script>
👉 <router-link :to="{name: 'bPage'}">
$router.push
로 B페이지 이동을router-link
를 사용해서 B페이지로 이동하면 된다.
Solution 2 : $router.push.catch 사용
<template>
<div>
<h1>A Page</h1>
<button @click="goToB">페이지이동</button>
</div>
</template>
<script>
export default {
methods:{
goToB() {
this.$router.push({name: 'bPage'}).catch( () => {
alert('잘못된 접근입니다.')
});
},
}
}
</script>
👉 this.$router.push({name: 'bPage'}).catch( () => { ... })
- B페이지로 이동 Redirect로 Error가 발생할 경우
catch
에서 error를 캐치 하여catch
내부에 작성된 로직이 실행 된다. - 현재 예제에서는 B페이지로 접근 후 Redirect가 발생한 경우
alert
을 띄운다 - 단, 사용자가 URL주소를 직접 입력해서 B페이지로 접근할 경우
catch
에서 인식하지 못해 A페이지로 Redirect가 될뿐catch
내부 로직은 실행되지 않는다.
B페이지 접근 조건을 체크하여 Redirect하는 기능은 다양하게 구현 할 수 있다.
Vue 라이프사이클 훅 중 하나인 created()
를 사용해 B페이지 접근 시 this.$route
로 route
정보를 확인하고 Redirect를 할지말지 정하면 된다.
라이프사이클 훅을 사용하면 Redirect에러를 만나지 않을 것 이다.
하지만 router를 체크하는 로직은 따로 분리 하고싶다는 생각을 했다.
component내부에서 사용하는 라우터가드 중 beforeRouteEnter()
를 사용하면 B페이지로 접근 할때 제일 먼저 router를 체크 할 수 있고 router만 체크하는 로직을 분리 할 수 있다는 생각에 다른 로직과 섞이지 않는다는 생각했다.
아직 개발 경력은 얼마 되지 않지만 코드를 짜면서 매번 느끼는건 "정답인 코드는 없는 것 같다."
모든 코드에 장단점은 있고 어떻게하면 단점보다 장점을 많이 가진 코드를 만들수 있을지 꾸준히 생각하고 만들어보고 직접 겪어보는게 정답인 것 같다.
분명한건 "원래 이렇게 해", "모르겠고 이렇게 해야만 해", "내 방식이 옳아"라는 생각을 가지는건 지양해야 된다고 생각한다.
잘못된 내용이나 보충이 필요한 내용이 있다면 댓글 남겨 주세요!
주니어 개발자에게 큰 도움이 됩니다! 감사합니다! 😃
Reference
- vue-router - Uncaught (in promise) Error: Redirected from "/login" to "/" via a navigation guard | Newbedev - Vue Router Redirected Error 해결책
- vue-router - Uncaught (in promise) Error: Redirected from "/login" to "/" via a navigation guard - Redirect중복 의견 글
'개발노트 > Vue' 카테고리의 다른 글
[Vue] Dom접근 하기 - $ref, $refs (0) | 2021.08.09 |
---|---|
[Vue] 이벤트 전달 - Props (0) | 2021.08.08 |
[Vue] 조건부 렌더링(v-if, v-show) (1) | 2021.08.04 |
[Vue] input에 숫자만 입력 가능하게 하기 (1) | 2021.08.02 |
[Vue] Naver 간편 로그인 (naverLogin_implicit-1.0.3.js) 구현 (2) | 2021.07.31 |
개발 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!