# 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); }; ```