# remix-backend
**Repository Path**: react_22/remix-backend
## Basic Information
- **Project Name**: remix-backend
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-11-15
- **Last Updated**: 2024-12-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Welcome to Remix!
- 📖 [Remix docs](https://remix.run/docs)
## Dependencies
- Use [daisyui](https://daisyui.com/)
- Install [remix-i18next](https://remix.run/resources/remix-i18next)
- Introduce to [remix-vite-i18next](https://github.com/sergiodxa/remix-vite-i18next)
- `pnpm add remix-i18next i18next react-i18next i18next-browser-languagedetector i18next-fetch-backend`
- `pnpm add -D vite-env-only`
- Install [remix-auth](https://remix.run/resources/remix-auth)
- Install [prisma](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project)
- `pnpm add -D prisma`
## Usage
- Valid a form
```tsx
// make a zod object in .server/models/xxx.ts
// To support internationalization with i18next, override the default Zod object messages in route file; e.g.
// from admin.permissions.tsx
const validate = zPermission.extend({
name: z.string().min(1, { message: `${t("name")} ${t("required")}` }),
zh_name: z.string().min(1, { message: `${t("zh_name")} ${t("required")}` }),
})
// and print the error message in the form
```
- Prisma
```shell
pnpm dlx prisma generate
pnpm dlx prisma migrate dev --name init
```
## Development
Run the dev server:
```shellscript
pnpm run dev
```
## Deployment
First, build your app for production:
```sh
pnpm run build
```
Then run the app in production mode:
```sh
pnpm start
```
Now you'll need to pick a host to deploy it to.
### DIY
If you're familiar with deploying Node applications, the built-in Remix app server is production-ready.
Make sure to deploy the output of `npm run build`
- `build/server`
- `build/client`
## Styling
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information.
### tailwindcss
* sm (small): 640px 及以上
* md (medium): 768px 及以上
* lg (large): 1024px 及以上
* xl (extra-large): 1280px 及以上
* 2xl (extra-extra-large): 1536px 及以上
### FAQ
- fetcher.submit()不会触发actionData刷新
- Q: `class="dark:..."` not work in tailwindcss
- A: add `darkMode: ['class', '[data-theme="dark"]']` in `tailwind.config.ts`
- Q: A component is changing an uncontrolled input to be controlled.
- A: 原代码` r.id!).includes(role.id!)}/>`, 如果 userInfo.roles 初始为 undefined 或者为空数组,React 会认为这是一个非受控组件(uncontrolled component)。当 userInfo.roles 发生变化时,React 会尝试将其转换为受控组件(controlled component),从而导致警告。所以改为`checked={(userInfo.roles ?? []).some(r => r.id === role.id)}`
- Q: 使用useRef来清除Timeout,在一个输入查询参数后自动触发查询,需要一个500ms的防抖程序(防止输入参数后立即查询)
- A:
```tsx
const [search, setSearch] = useState("");
const debounceTimeout = useRef(null);
const handleSearch = (e: React.ChangeEvent) => {
const value = e.target.value;
setSearch(value);
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}
debounceTimeout.current = setTimeout(() => {
reloadTableData(pagination, sort, value);
}, 500);
};
```