
2024.02.29(목)

npm i -D @craco/craconpm i -D craco-aliastsconfig.json에서 직접 추가해도 되지만 root에 tsconfig.paths.json 생성하고 tsconfig.json에서 extends field에 추가tsconfig.json{
  "compilerOptions": { … },
  **"extends": "./tsconfig.paths.json",**
  "include": ["src"]
}tsconfig.paths.json{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/*": ["src/*"]
        }
    }
}craco.config.js 생성하고 tsconfig.json에서 include field에 추가craco.config.js 🔗const cracoAlias = require("craco-alias");
module.exports = {
    plugins: [
        {
            plugin: cracoAlias,
            options: {
                source: "tsconfig",
                baseUrl: ".",
                tsConfigPath: "tsconfig.paths.json",
                debug: false,
            }
        }
    ]
};tsconfig.json{
  "compilerOptions": { … },
  "extends": "./tsconfig.paths.json",
  "include": ["src", **"craco.config.js"**]
}package.json의 scripts에서 start, build, test를 craco를 통해 할 수 있도록 수정 🔗{
	…,
  "scripts": {
    "start": "**craco** start",
    "build": "**craco** build",
    "test": "**craco** test",
    "eject": "react-scripts eject",
    "typecheck": "tsc --noEmit --skipLibCheck"
  },
	…
}App.tsx현재 router에서 중복 발생
<Layout> componenterrorElement: <Error />createBrowserRoute에 전달되는 routeList를 간단하게 만들고 map으로 순회하며 중복되는 부분을 추가
⁝
const routeList = [
  {
    path: "/",
    element: <Home />
  },
	…,
  {
    path: "/orderlist",
    element: <OrderList />
  },
];
const router = createBrowserRouter(
  routeList.map((item) => {
    return {
      ...item,
      element: <Layout>{item.element}</Layout>,
      errorElement: <Error />
    }
  })
);
⁝
const response = await httpClient~; return response.data;가 계속 중복되어서 http.ts에서 requestHandler를 만드는 식으로 refactoring했는데 나는 굳이 필요성을 느끼지 못해서 하지 않았다.typescriptreact.json{
	"reactFunctionComponentWithSC": {
		"prefix": "_component-sc",
		"body": [
			"import styled from 'styled-components';",
			"",
			"function ${1:${TM_FILENAME_BASE}}() {",
			"    return (",
			"        <${1:${TM_FILENAME_BASE}}Style>",
			"            <h1>${1:${TM_FILENAME_BASE}}</h1>",
			"        </${1:${TM_FILENAME_BASE}}Style>",
			"    );",
			"}",
			"",
			"const ${1:${TM_FILENAME_BASE}}Style = styled.div``;",
			"",
			"export default ${1:${TM_FILENAME_BASE}};"
		],
		"description": "Creates a React Arrow Function component with Styled Components"
	},
	"const arrow function": {
		"prefix": "_const-func",
		"body": [
			"const ${1:func} = () => {",
			"  ",
			"};"
		]
	},
	"styled component theme value": {
		"prefix": "_theme-styled",
		"body": "${({ theme }) => theme.$1}"
	},
	"useEffect template": {
		"prefix": "_effect",
		"body": "useEffect(() => {\r\n    $2\r\n}, [$1]);"
	},
	"Title component": {
		"prefix": "_title-comp",
		"body": "<Title size=\"$1\" color=\"$2\">\r\n    $3\r\n</Title>"
	},
	"Button component": {
		"prefix": "_btn-comp",
		"body": "<Button size=\"$1\" scheme=\"$2\">\r\n    $3\r\n</Button>"
	}
}_를 붙이는게 찾기 좋음useAuth Hook 만들기Powerful asynchronous state management (version up을 하면서 TanStack Query로 이름이 바뀜)
npm i @tanstack/react-query --saveQueryClientQueryClientProvider: QueryClient를 app 전반에 연결하고 제공하기 위해 사용useQuery Hook: 기존 custom hook의 useState와 useEffect를 한번에 처리!useQuery({
	queryKey: [dep1, dep2, …],
	queryFn: () => fetchSomething(dep2),
});queryKey: query 식별자, queryFn이 의존하는 변수를 넣는다면 dependency처럼 동작 (순서 상관 X)queryFn: 쿼리가 데이터를 요청할 때 호출되는 함수 (queryKey가 변경되면 호출됨)data: query가 성공적으로 가져온 가장 최신 데이터 (queryFn 반환 값)isLoading: query의 데이터를 가져오는 중인지 여부, isFetching && isPending과 동일useBooks.ts에 React Query 적용: 구현 코드 Commit 바로가기