[React] 대시보드 특화 프레임워크 Refine 맛보기
💡 refine을 이용하여 간단한 CRUD 페이지를 개발할 수 있다. (feat. Taliwind.css)
공식 documnet, github
Refine 이란?
refine 은 웹 애플리케이션의 빠른 개발을 위한 React 기반 프레임워크
- CRUD api 같은 반복적인 작업을 없애고
- 인증, 액세스 제어, 라우팅, 네트워킹, 상태 관리 및 i18n과 같은 중요한 부분에 대한 업계 표준 솔루션을 제공.
- 또한 무제한적인 스타일링 및 사용자 지정 옵션을 제공하는 디자인으로 정교함을 제공.(=headless)
(=UI 라이브러리는 제공하지 않아서 디자인에 한해선 커스텀이 자유롭다는 뜻... 🙂)
왜 Refine 인가?
- 간편한 사용법
- 관리 패널, 대시보드 및 내부 도구와 같은 데이터 집약적인 애플리케이션에 특화
- 내장된 SSR 지원으로 storefront 어플리케이션에도 특화
- 요구사항이 단순한 경량 프로젝트에 권장
- (+) data-provider, auth-provider를 제공해준다.(API Referece-Core API-Providers에서 확인 가능)
- 관리자 페이지 개발시 auth-provider에서 login, logout, checkAuth 정도 사용할듯
Refine의 중점 기능들
- ⚙ CLI를 이용한 초간단 세팅
- 🔌 REST API, GraphQL, NestJs CRUD, Airtable, Strapi, Strapi v4, Strapi GraphQL, Supbase, Hasura, Nhost, Appwrite, Firebase, Directus 및 Altogic을 포함한 15개 이상의 백엔드 서비스용 커넥터
- 🌐 Next.js 또는 Remix를 통한 SSR 지원
- ⚛ 리액트 쿼리로 상태 관리 및 뮤테이션을 완벽하게
- 🔀 원하는 라우터 라이브러리를 사용한 고급 라우팅
- 🔐 원활한 인증 및 액세스 제어 흐름을 위한 provider 제공
- ⚡ 라이브/실시간 애플리케이션 지원
- 📄 간편한 로그 및 문서 버전 관리
- 💬 모든 i18n 프레임워크 지원
- 💪 미래보장, 지속가능한 아키텍처
- ✅ 테스트 커버리지 100%
이 정도 되는데 내 기준으론 REST API, NestJS CRUD를 사용하기 편하고 라우팅과 provider 제공이 편리해서 사용하기로 했다.
Refine 튜토리얼 (with Tailwind.css)
(+) Refine 관계없이 개인적으로 공부한 프로젝트 구조
components
여러 페이지에서 공통적으로 사용하는 컴포넌트들로 구성
interfaces
컴포넌트의 props에 대한 타입들로 구성(types와 같음. typescript에서는 interfaces를 주로 쓰는 듯)
pages
페이지(라우터) 단위의 컴포넌트 폴더들로 구성 (백엔드에서 도메인 단위로 모듈 나누는 거랑 같은 느낌…)
JSX functional component(**.tsx)
함수형 컴포넌트. - 이 컴포넌트들을 App.tsx가 모아 화면에 뿌린다. 클래스형에 비해 hook이 걸릴 때만 재렌더링을 하기 때문에 비용이 적게 들고 성능이 좋다. (hook은 state, life cycle 관리에 쓰이는 기능)
App.tsx
실제 브라우저 화면에 보이는 컴포넌트 - App.tsx를 export 하여 index.tsx가 import 하고 그걸 index.html이 받아서 (root라는 id를 가진 div에) 화면에 보여준다.
index.tsx
App.tsx에 모인 컴포넌트를 public/index.html과 연결해주는 파일. - index.tsx들은 매개체 역할을 한다.
1. 프로젝트 세팅
create-react-app 커맨드를 사용
프로젝트 생성: npx create-react-app@5.0.1 my-app --template typescript
🛹 추가해야 할 패키지들
- for Simple REST Dataprovider
@pankod/refine-simple-rest - for Using useTable hook
@pankod/refine-react-table - for Tailwind.css
tailwindcss postcss autoprefixer (dev) - for Using useForm hook
@pankod/refine-react-hook-form- (+) react-hook-form 맛보기
useEffect & useState는 대표적으로 사용하는 hook들
useEffect → life cycle, 사이드 이펙트 관리. useEffect 내에서 훅을 쓸 수 있다(훅인훅…)
위에처럼 하는 건 손이 많이 간다. react hook form 을 사용하면 더 간단하게 구현할 수 있다.const [v, setV] = useState(…) <input value = {v}; onChange = {(e) ⇒ setV(e.target.value)}
- (얼마나 간단하게 되는지는 모르겠지만 이 글을 보면 효과가 큰 모양이다..)
- useEffect( () ⇒ { setA(3); return () ⇒ (ws.disconnect()); }, [a]); // a가 바뀌었을 때 useEffect가 활성화되어 재렌더링된다. 빈 배열일 경우 초기화될 때 돌아간다.
- useState → state 관리 때 사용
- 참고 링크는 여기
- (+) react-hook-form 맛보기
yarn add @pankod/refine-simple-rest @pankod/refine-react-table @pankod/refine-react-hook-form
yarn add tailwindcss postcss autoprefixer -D
2. 애플리케이션 부트스트랩
// src/App.tsx
import { Refine } from "@pankod/refine-core";
import routerProvider from "@pankod/refine-react-router-v6";
import dataProvider from "@pankod/refine-simple-rest";
const App: React.FC = () => {
return (
https://api.fake-rest.refine.dev>")}
/>
);
};
export default App;
refine 애플리케이션에서 사용하는 root 컴포넌트 dataProvider 애플리케이션 전역에서 simple rest dataprovider를 사용할 수 있게 한다. 이후 yarn start로 실행하면 http://localhost:3000 에서 웰컴 페이지를 확인할 수 있다.
3. 리소스 추가
// src/App.tsx
...
import { PostIcon } from "./icons";
export const App: React.FC = () => {
return (
<Refine
...
resources={[{ name: "posts", icon: PostIcon }]}
/>
);
};
// icons.tsx
export const PostIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
<polyline points="2 17 12 22 22 17"></polyline>
<polyline points="2 12 12 17 22 12"></polyline>
</svg>
);
4. Tailwind CSS 추가
// tailwind.config.js
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
// src/App.tsx
...
import 'index.css';
(+) css 설정을 추가하고 싶으면 base 와 components 사이에 넣어줘야 한다.
이후 아래 기능들은 공식 튜토리얼에서 이어갈 수 있다.
- Layout 생성
- 게시물 목록(페이지네이션, 정렬 및 필터 포함)
- 게시물 상세 페이지
- 게시물 수정, 생성, 삭제
완성된 프로젝트는 다음과 같다.
참고 자료
[React] Hooks 이해하기( useState, useEffect )
React - Functional Component의 장점, Hook
[React]TypeScript기반 Type Alias vs interface
004_Create React App 기본 구조에 대해 알아보자!
React | 리액트로 프로젝트를 진행할때 어떻게 폴더와 컴포넌트 구조를 설계하는 것이 좋을까?🤔
react-hook-form을 선택한 이유와 적용 과정
refine | Build your React-based CRUD applications, without constraints! | refine
https://github.com/refinedev/refine