-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[김유경] Week20 #1069
The head ref may contain hidden characters: "part4-\uAE40\uC720\uACBD-week20"
[김유경] Week20 #1069
Conversation
useEffect의 dependency에 data를 추가하여 해결
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
const { handleUserDataState } = useContext(UserContext); | ||
const router = useRouter(); | ||
const [profile, setProfile] = useState({ | ||
auth_id: "", | ||
email: "", | ||
image_source: "", | ||
}); | ||
const Location = useRouter(); | ||
const LocationPath = Location.pathname; | ||
const { data: profile } = useQuery({ | ||
queryKey: ["loginUserProfile"], | ||
queryFn: getLoginUserInfo, | ||
}); | ||
|
||
async function handleLoadUserInfo() { | ||
try { | ||
const { data } = await getLoginUserInfo(); | ||
const { email, image_source, auth_id } = data[0] || []; | ||
setProfile({ | ||
auth_id: auth_id, | ||
email: email, | ||
image_source: image_source, | ||
}); | ||
handleUserDataState({ userId: auth_id }); | ||
} catch (error) { | ||
router.push("/signin"); | ||
useEffect(() => { | ||
if (profile) { | ||
handleUserDataState({ isLogin: true, userId: profile.id }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useQuery로 받아오는 데이터가 1초마다 계속해서 받아오다보니, useContext의 데이터도 계속해서 새로 받아지는 것 같습니다. 무한 렌더링...이 되고 있는 것 같은데 이런 경우에 useQuery말고 그냥 fetch 함수를 사용하는 것이 방법일지, useQuery 말고도 다르게 개선할 수 있는지 궁금합니다 ...!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음.. 1초마다 계속해서 요청을 한다는 말씀이실까요?!?
제가 확인해보니 위 이유보다는 useEffect
의 의존성 배열에 handleUserDataState
가 있는게 문제인거 같아요! 함수의 경우는 매 렌더링 시 새롭게 생성되어 참조값이 변하기 때문에 무한 루프에 빠지게 되는 원인이 될 수 있어요! 그래서 일반적으로는 함수에 직접 의존하는 순수한 값만 넣어주는게 좋아요!
해당 의존성 배열에서 handleUserDataState
를 제거하면 문제가 사라집니다!
export const ModalDim = styled.div` | ||
export const ModalDim = styled.button` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넘겨주는 함수의 매개변수 타입이 event : MouseEvent라서 태그를 버튼으로 바꿨는데, 그것보단 타입을 ButtonElement 말고 HTMLElement 로 바꾸는게 더 적절한 지 여쭤보려고 했으나 적으면서 생각해보니 그게 더 적절한 것 같습니다.
const router = useRouter(); | ||
const { loginData } = useContext(UserContext); | ||
|
||
const handleGoFolders = () => { | ||
if (loginData.isLogin) { | ||
router.push("/folder"); | ||
} else { | ||
router.push("/signin"); | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위의 useContext 무한 렌더링 때문인지, 이 부분이 정상적으로 작동하지 않습니다. url은 바뀌지만 리다이렉트 되지 않는 문제가 있습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 앞서 말한 useEffect
의 의존성에서 handleUserDataState
를 제거하면 해결될 거 같아요~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
20주차 미션 고생 많으셨습니다 유경님🎉
고민의 흔적이 코드에서 보이는거 같아서 개인적으로 좋은 경험이었어요! ㅎㅎ 고생하셨습니다:)
질문에 대한 답변은 코드 리뷰 내에 작성했으니 확인해주시면 됩니다!
const [selectFolderId, setSelectFolderId] = useState<number>(); | ||
const addToFolderMutation = useMutation({ | ||
mutationFn: ({ url, folderId }: { url: string; folderId: number }) => | ||
postAddToFolder({ url: url, folderId: folderId }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중요하지는 않은 부분이지만 postAddToFolder({url, folderId})
로 축약할 수 있을거 같아요!
export interface DeleteLinkProps extends BaseModalProps { | ||
deleteURL: string; | ||
linkId: number; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기본 공통 속성 상속 받아서 처리하는거 좋네요👍👍
const { data: profile } = useQuery({ | ||
queryKey: ["loginUserProfile"], | ||
queryFn: getLoginUserInfo, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useQuery
에 대해서는 멘토링 시간에 따로 이야기드리도록 하겠습니다!
const { handleUserDataState } = useContext(UserContext); | ||
const router = useRouter(); | ||
const [profile, setProfile] = useState({ | ||
auth_id: "", | ||
email: "", | ||
image_source: "", | ||
}); | ||
const Location = useRouter(); | ||
const LocationPath = Location.pathname; | ||
const { data: profile } = useQuery({ | ||
queryKey: ["loginUserProfile"], | ||
queryFn: getLoginUserInfo, | ||
}); | ||
|
||
async function handleLoadUserInfo() { | ||
try { | ||
const { data } = await getLoginUserInfo(); | ||
const { email, image_source, auth_id } = data[0] || []; | ||
setProfile({ | ||
auth_id: auth_id, | ||
email: email, | ||
image_source: image_source, | ||
}); | ||
handleUserDataState({ userId: auth_id }); | ||
} catch (error) { | ||
router.push("/signin"); | ||
useEffect(() => { | ||
if (profile) { | ||
handleUserDataState({ isLogin: true, userId: profile.id }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음.. 1초마다 계속해서 요청을 한다는 말씀이실까요?!?
제가 확인해보니 위 이유보다는 useEffect
의 의존성 배열에 handleUserDataState
가 있는게 문제인거 같아요! 함수의 경우는 매 렌더링 시 새롭게 생성되어 참조값이 변하기 때문에 무한 루프에 빠지게 되는 원인이 될 수 있어요! 그래서 일반적으로는 함수에 직접 의존하는 순수한 값만 넣어주는게 좋아요!
해당 의존성 배열에서 handleUserDataState
를 제거하면 문제가 사라집니다!
|
||
function toggleContents(event: MouseEvent<HTMLButtonElement>) { | ||
event.preventDefault(); | ||
setIsOpenContents(!isOpenContents); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
state를 업데이트할 때는 함수형 업데이트를 사용하는게 보다 안전한 방식입니다!
<Button onClick={handleCategoryActive} id={null} value="전체"> | ||
전체 | ||
</Button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id
에 null
을 넣어주신 특별한 이유가 있으실까요?!?
const router = useRouter(); | ||
const { loginData } = useContext(UserContext); | ||
|
||
const handleGoFolders = () => { | ||
if (loginData.isLogin) { | ||
router.push("/folder"); | ||
} else { | ||
router.push("/signin"); | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 앞서 말한 useEffect
의 의존성에서 handleUserDataState
를 제거하면 해결될 거 같아요~!
userId: "", | ||
userId: 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0으로 초기값을 넣어주신 이유가 있으실까용?
초기값이 없다면 null
을 넣어주는게 좋아보여요!
import { axiosInstance } from "./axiosInstance"; | ||
|
||
export async function deleteFolder({ | ||
folderId, | ||
}: { | ||
folderId: number | string; | ||
}) { | ||
const response = await axiosInstance.delete( | ||
`/linkbrary/v1/folders/${folderId}` | ||
); | ||
|
||
return response.status; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금은 API Error에 대한 별도의 처리가 없는거 같아요!
axios intercepter를 보게 되면 에러가 발생했을 때, Promise.reject(error)
처리를 하고 있는데 이 에러를 처리하는 부분이 따로 안보이는거 같네용?
useMutation
을 사용하시면 onError 콜백을 사용해서 에러를 처리할 수 있습니다!
++
추가적으로 API를 관리하는 방식에 대해서 드리고 싶은 말이 있는데, 이 부분은 멘토링 때 이야기 하도록 할게요!
const ACCESS_TOKEN = "accessToken"; | ||
const REFRESH_TOKEN = "refreshToken"; | ||
|
||
export const setToken = (accessToken: string, refreshToken: string) => { | ||
if (typeof window !== "undefined") { | ||
localStorage.setItem(ACCESS_TOKEN, accessToken); | ||
localStorage.setItem(REFRESH_TOKEN, refreshToken); | ||
} | ||
}; | ||
|
||
export const getToken = () => { | ||
if (typeof window !== "undefined") { | ||
const accessToken = localStorage.getItem(ACCESS_TOKEN); | ||
const refreshToken = localStorage.getItem(REFRESH_TOKEN); | ||
|
||
return { accessToken, refreshToken }; | ||
} | ||
}; | ||
|
||
export const removeToken = () => { | ||
if (typeof window !== "undefined") { | ||
localStorage.removeItem(ACCESS_TOKEN); | ||
localStorage.removeItem(REFRESH_TOKEN); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
토큰 관련 로직 하나의 파일로 관리하는거 좋네요!
cf45e50
into
codeit-bootcamp-frontend:part3-김유경
요구사항
기본
주요 변경사항
멘토에게
useContext와 react-query를 사용하다, 아래와 같은 오류를 만났고 useEffect의 dependency list로 useQuery에서 받아온 데이터를 넣어주고 있어서 1초마다 리렌더링 되는 것 같습니다. 하지만...어떻게 해결해야하는지 떠오르지 않습니다....ㅠㅠ
셀프 코드 리뷰를 통해 질문 이어가겠습니다.