React
리팩토링
너무 오랜만에 남기는 거라 작성해야 될 게 많이 남았지만 현재 작성하고 있는 부분까지만 작성해본다.
useQuery 사용하기
Login.tsx
npm install react-query
를 설치한다.- 타입스크립트의 타입을 위해
npm install @types/react-query
또한 설치한다.
- 타입스크립트의 타입을 위해
컴포넌트에서 Query 사용을 위해 최상위 컴포넌트인 App.tsx에서
QueryClient
를 선언 후 컴포넌트를 감싸준다.1 2 3
const queryClient = new QueryClient(); return <QueryClientProvider client={queryClient}></QueryClientProvider>;
쿼리를 추적하기 위해
ReactQueryDevtools
또한 하단에 작성한다.1 2 3 4 5
import { ReactQueryDevtools } from "react-query/devtools"; return( <ReactQueryDevtools></ReactQueryDevtools>; )
기존에 axios를 사용하여 작성된 코드를
useQuery
로 변경한다.// 기존 코드 const loginApi = () => { axios.get<LoginUser[]>("http://localhost:4000/login").then((res) => { const matchedUser = res.data.find( (user) => user.id === id && user.pass === pw ); if (matchedUser) { // 로그인 성공 처리 setLoginValue(!loginValue); setMessage(true); } else { // 로그인 실패 처리 setMessage(false); } });}
async function login() { const res = await axios.get("http://localhost:4000/login"); return res; } const { data, isLoading, isError, error } = useQuery("get", () => login(), { refetchOnWindowFocus: false, }); const loginApi = async () => { const response = await axios.get("http://localhost:4000/login"); const matchedUser = response.data.find( (user: LoginUser) => user.id === id && user.pw === pw ); if (matchedUser) { // 로그인 성공 처리 setLoginValue(!loginValue); setMessage(true); } else { // 로그인 실패 처리 setMessage(false); } };
SignPage.tsx
꽤나 애먹었던 SignPage 리팩토링… api부터 error처리까지, 그리 어렵지 않다고 생각하던 게 정말 오래 걸렸다.
post 요청을 보낼 함수를 작성한다.
- 처음 작성한 코드는 post를 요청하는 함수에서 에러를 처리하려 했으나, api에서 요청을 보낼 때 유효성 검사를 진행 후 상태코드를 전달하는 방식으로 처리하면 된다.
- 이렇게 작성하면
signIn
함수의 조건문을 전부 지워줘도 된다. - api 코드에 작성된 유효성 검사가 진행되지 않았는데 endpoint가 같아서 작동되지 않아서 login 엔드포인트를 공유하던 것을 signin으로 바꿔줬다.
1 2 3 4 5 6 7
async function signIn(idPw: LoginUser) { const res = await axios.post("http://localhost:4000/signin", idPw); if (res.data === "id나 pw가 없습니다.") setIdError(res.data); else if (res.data === "중복되는 아이디입니다.") setIdError(res.data); else setIdError(""); return res; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
app.post("/signin", (req, res) => { const { id, pw } = req.body; if (!id || !pw) { console.log("id나 pw가 없습니다."); return res.status(400).json({ message: "id나 pw가 없습니다." }); } const alreadyId = login.find((user) => user.id === id); console.log(login.find((user) => user.id === id)); if (alreadyId !== undefined) { console.log("중복되는 아이디입니다."); return res.status(400).json({ message: "중복되는 아이디입니다." }); } login.push({ id, pw }); console.log(login); return res.json(login); });
회원가입에 대한 처리는
useMutation
을 사용하여 처리했다.- 처음엔 onError와 onSuccess를 활용하지 않고 state를 활용하는 방식으로 에러를 처리하는 삽질도 오래 했다.
- 다음엔 내장 함수를 적극 활용하도록 하자.
- 타입에러도 많이 떴는데 err의 response의 에러 메시지를 가져오고 싶었으나 타입 에러가 많이 발생했다.
- AxiosError 타입이 있으니 이를 지정해주고, 데이터를 받는 비동기 함수의 unknown 타입이므로 optional을 사용해준다.
1 2 3 4 5 6 7
const postSignIn = useMutation((idPw: LoginUser) => signIn(idPw), { onError: (err: AxiosError<ResponseData>) => alert(err.response?.data?.message), onSuccess: () => { alert("회원 가입에 성공했습니다."); }, });