react-todo-app 1주차 1/2

권현경·2022년 11월 1일
0
post-custom-banner

1. client와 server 분리

가장 먼저 미리 구현되어 있던 API 관련 파일들을 server 폴더 아래에 옮겼다. 이후 CRA를 사용하여 client 세팅을 해주었다.

1차 고비

이때 아래와 같은 에러가 나면서 CRA가 동작하지 않았다.

You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.1).
We no longer support global installation of Create React App.

최근 버전의 create-react-app에서는 패키지가 글로벌하게 설치되는 것을 막고 있나보다. 아래와 같이 입력하여 create-react-app을 제거해준 뒤 다시 설치하니 제대로 동작하였다.

npm uninstall -g create-react-app
yarn global remove create-react-app

2. 절대경로 설정

처음에 craco라는 라이브러리를 통해 설정하려 하였으나 CRA 4 버전까지만 지원하기 때문에 실패하였다. 그래서 다른 방법으로 시도해보았다. 참고링크

  1. tsconfig.json 파일에 아래 내용을 추가
// tsconfig.json
{
  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "@/components/*": ["src/components/*"]
    }
  }
}

이제 IDE에서 절대경로를 사용할 수 있게 되었으나 브라우저에서 실행했을 때 파일을 찾을 수 없다는 에러가 나온다.

이는 typescript 컴파일 시에 tsconfig를 활용하여 경로 추적이 가능하지만, 실제 webpack 번들에서는 해당 경로가 고려되지 않은 채 빌드되기 때문이라고 한다. 번들 파일이 생성되고, 브라우저에서 스크립트 실행 시 해당 경로를 추적하지 못하여 모듈을 찾지 못하는 에러가 발생하는 것이다.

빌드 시 경로 설정을 해주려면 webpack.config에서의 경로 설정이 필요한데 eject를 해야한다는 단점이 있다. 그래서 사용하게 된 것이 react-app-rewired이다. 이는 craco처럼 eject를 하지 않고 webpack 구성을 할 수 있게 도와주는 라이브러리이다.

  1. webpack 설정 변경
    가장 먼저 react-app-rewired와 customize-cra 모듈을 설치해준다.
npm install react-app-rewired customize-cra

2-1. package.json의 scripts 수정

  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },

2-2. config-overrides.js 파일 추가

const { override, addWebpackAlias } = require("customize-cra");
const path = require("path");

module.exports = override(
  addWebpackAlias({
    "@": path.resolve(__dirname, "src/"),
  })
);

위와 같이 추가하여 webpack 설정을 오버라이드하고 커스터마이징할 수 있다.

3. react-query 추가

tanstack/react-query와 react-query

다른 사람들이 어떻게 챌린지 작업을 했는지 보고 있는데 react-query가 아닌 tanstack/react-query를 사용하고 있는 걸 보았다. 무슨 차이인가 싶었는데 tanstack/react-queryreact-query가 리브랜딩된 버전이라고 한다. 버전 4부터는 tanstack/react-query에서 업데이트 되기로 했다고 하니 나도 이걸로 선택하게 되었다.

QueryClient 설정

retry 옵션은 API가 실패하면 설정한 값만큼 재시도 하는 옵션이다. 0으로 설정하면 재시도하지 않고 유저에게 빠른 응답을 보여줄 수 있다. 현재 나는 서버 이슈까지는 고려할 필요가 없으므로 0으로 설정하였다.

useErrorBoundary옵션은 리액트16 이상에서 제공하는 Fallback UI 설정에 대한 옵션이다. 에러 상황시 어떻게 되는지 테스트해보고 싶어 queries와 mutations에 true 값으로 설정하였다.

new QueryClient({
  defaultOptions: {
    queries: {
      retry: 0,
      useErrorBoundary: true,
    },
    mutations: {
      useErrorBoundary: true,
    },
  },
});

2차 고비

회원가입 페이지를 만들면서 공식 문서에 나온대로 아래와 같이 useMutation을 작성해보았다.

 const mutation = useMutation({
    mutationFn: (variables) => {
      return axios.post("http://localhost:8080/users/create", variables);
    },
  });

  const onSubmit = (data: FormData) => {
    mutation.mutate({
      [EMAIL]: data[EMAIL],
      [PASSWORD]: data[PASSWORD],
    });
  };

그런데 아래와 같이 type 에러가 떴다.

TS2345: Argument of type '{ email: string; password: string; }' is not assignable to parameter of type 'void'

useMutation을 (커맨드)클릭해서 어떻게 만들어져 있는지 보니 아래와 같이 되어있었다. 여기서 TVariables 부분이 void로 디폴트 설정이 되어있었던 것이다.

export function useMutation<
  TData = unknown,
  TError = unknown,
  TVariables = void,
  TContext = unknown,
>(
  options: UseMutationOptions<TData, TError, TVariables, TContext>,
): UseMutationResult<TData, TError, TVariables, TContext>

아래와 같이 직접 타입을 지정해주었더니 에러가 사라졌다. 나머지 값들도 작업하면서 필요에 따라 넣어줘야겠다.

interface SignUpVariable {
  email: string;
  password: string;
}

const mutation = useMutation<unknown, unknown, SignUpVariable, unknown>({
    mutationFn: (variables) => {
      return axios.post("http://localhost:8080/users/create", variables);
    },
  });
profile
프론트엔드 개발자
post-custom-banner

0개의 댓글