- 2023.06.27 오류 발견 및 내용 업데이트
PART 1. sequlize findOne 메서드의 null return
설명
개발 환경
- back : express + sequlize + ts
- from : nextjs + redux toolkit + ts
sequlize 의 findOne 메서드를 통해 데이터베이스의 내용을 조회하는 기능을 구현했다.
try-catch 문안에서 조회 성공 시 2xx 번대 실패 시 4xx, 5xx 번대 상태코드로 반환하여 redux toolkit 기능들을 활용 비동기 작업을 처리하고 있는 와중 잘못된 요청에도 데이터 없이 화면이 나타나고 redux 의 state, api 요청 역시 에러관련 내용이 없었고 값은 있어야 할 state 의 값이 null 인 이상한 상황이 나왔다.
알고 보니 sequlize 의 findOne 메서드는 조회한 결과가 없을 경우 null 을 반환하기 때문에 try-catch 문안에서 오류로써 예외처리되지 않으며 정상적으로 2xx 번대 상태로 값이 넘어온 것
그래서 아래와 같이 값이 존재하지 않을 때 404 코드로 오류가 있음을 알려 reducer 가 오류임을 인지하고 예외처리를 할 수 있게 수정했다.
코드
// sequlize 모델 형식의 BalanceDebatePost
import BalanceDebatePost from "@models/balanceDebatePost";
router.get("", async (req, res, next) => {
try {
const balanceDebatePostData = await BalanceDebatePost.findOne({
...
});
// 조회한 데이터가 존재하지 않을 때
if (!balanceDebatePostData)
res.status(404).json({ message: "존재하지 않는 게시글입니다" });
// 정상적으로 조회한 데이터가 있을 때
res.status(200).json(balanceDebatePostData);
} catch (error) {
// 에러 발생 시
next(error);
}
});
PART 2. 비동기 데이터로 jsx 구성 예외 처리 및 최적화
설명
위 문제를 겪으면서 다른 수정할 점이 있음을 느꼈다.
ts 환경에서 비동기 데이터를 활용하여 jsx를 구성한다면 비동기 데이터의 타입이 null, undefined 등 타입을 확정 지을 수 없으므로 eslint 환경에 따라 오류를 띄울 것이며 작업하는 입장에서도 명확하지 않다.
api 서버에서 오류는 아니지만 비정상적인 데이터가 들어올 수 있고 이 경우 api 요청, 응답, 저장하는 과정에서도 오류를 인지하지 못할 수 있으며 웹 서버에서는 비정상적인 데이터임에도 jsx 를 구성하는 소요가 생긴다
해결 방법
개인적인 방법이고 참고만 하는 것이 적절해보임
1. API 요청 상황에서 예외 처리
- SSR 환경에서 랜더링 이전에 진행되는 api 요청에서 오류 발생 시 302 코드 반환하여 바로 리다이렉트 시켜 불필요한 랜더링을 사전 차단
코드
import { getIssueDebatePost } from "@store/slices/issueDebatePost" // API 요청 reducer
import { wrapper } from "@store/store" // next-redux-wrapper 내용
// next-redux-wrapper SSR 구현 메서드
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ req, res, query }) => {
const { pid } = query
if (pid) {
try {
// dispatch
await store.dispatch(getIssueDebatePost(pid as string)).unwrap()
} catch (error) {
console.log(error)
// 리다이렉션
res.writeHead(302, { Location: '/' })
res.end()
}
}
return { props: {} }
},
)
2. 컴포넌트 내에서 예외처리
A. 컴포넌트 내에서 특정 데이터가 없으면 빈 태그를 반환하게 구성하고 useEffect 를 통해 마찬가지로 특정 데이터가 없으면 페이지 이동 시키는 코드를 구성하여 불필요하게 jsx 구성하지 않는다.- 위 방법의 치명적이 오류가 있어 업데이트 하려함 - 2023.06.27
- 뒤로가기 버튼을 눌러 페이지가 이동되는 중에 useEffect 의존성 배열안에 있는 postData 의 데이터를 인식해 페이지가 이동되는 오류가 존재함 (단순히 if 안에 위치해도 안에 내용이 실행됨)
- 결론적으로 postData 의 값을 기준으로 페이지 이동을 시킨다면 불필요한 페이지 이동이 일어남
- 개선된 방식을 찾아 업데이트 예정
코드(오류가있음)
import React, { useEffect } from 'react'
import { useAppSelector } from '@store/store'
import { useRouter } from 'next/router'
const IssuePostPage = () => {
const router = useRouter()
const postData = useAppSelector((state) => state.issueDebatePost.postData)
// 초기 랜더링이후 데이터가 없다면 화면이동
useEffect(() => {
const isPostNull = async () => {
if (!postData) router.push('/debate-forum')
}
isPostNull()
}, [postData, router])
// 데이터가 존재하지 않으면 빈 태그 반환
if (!postData) return <></>
// 데이터가 존재하면 일반적인 jsx 구성요소 반환
return <p>jsx 구성요소</p>
}
export default IssuePostPage
- B. 특정 데이터 상태에 따라 대체 콘텐츠를 반환하는 코드를 구성
import React from 'react'
import { useAppSelector } from '@store/store'
const IssuePostPage = () => {
const { getPostError, postData } = useAppSelector((state) => state.issueDebatePost)
// 오류 발생시
if (getPostError || !postData) return <>오류 발생시 대체 jsx 구성요소</>
// 데이터가 존재하면 일반적인 jsx 구성요소 반환
return <>jsx 구성요소</>
}
export default IssuePostPage
'nextjs' 카테고리의 다른 글
[error] next/image Un-configured Host (0) | 2023.07.10 |
---|---|
커스텀 crousel (nextjs + ts + styled-components) (0) | 2023.04.20 |
Next.js 에 <Link /> 는 무엇인가 (0) | 2023.04.06 |
Next.js getServerSideProps 에서 페이지 이동 방법 (0) | 2023.03.31 |
nextjs 기타 지원 기능 (0) | 2023.02.02 |