Remix 集成 MUI

news2024/11/26 2:39:48

Remix 如何接入 MUI 组件库,MUI 官网提供了一个 Remix 接入 MUI 的例子,用的是老的 Remix版本,如何接入新的 Vite 版本呢?

由于 MUI 支持 SSR,只需要改造对应的 Client 和 Server 即可实现。安装 MUI 组件组件库,修改对应的 Client/Server 文件,代码如下:

安装 MUI

npm install @mui/material @emotion/react @emotion/styled @mui/icons-material

创建 MUI Provider

import { CacheProvider } from "@emotion/react";

import { ThemeProvider } from "@mui/material";
import theme from "./theme";
import createCache from "@emotion/cache";

function createEmotionCache() {
  return createCache({ key: "css" });
}

export function MuiProvider({ children }: { children: React.ReactNode }) {
  const cache = createEmotionCache();

  return (
    <CacheProvider value={cache}>
      <ThemeProvider theme={theme}>{children}</ThemeProvider>
    </CacheProvider>
  );
}

修改 client、server

### entry.client.tsx
/**
 * By default, Remix will handle hydrating your app on the client for you.
 * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
 * For more information, see https://remix.run/file-conventions/entry.client
 */

import { RemixBrowser } from "@remix-run/react";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { MuiProvider } from "./mui/MuiProvider";

startTransition(() => {
  hydrateRoot(
    document,
    <StrictMode>
      <MuiProvider>
        <RemixBrowser />
      </MuiProvider>
    </StrictMode>
  );
});
### entry.server.tsx
/**
 * By default, Remix will handle generating the HTTP Response for you.
 * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
 * For more information, see https://remix.run/file-conventions/entry.server
 */

import { PassThrough } from "node:stream";

import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";
import { MuiProvider } from "./mui/MuiProvider";

const ABORT_DELAY = 5_000;

export default function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext,
  // This is ignored so we can keep it in the template for visibility.  Feel
  // free to delete this parameter in your app if you're not using it!
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  loadContext: AppLoadContext
) {
  return isbot(request.headers.get("user-agent") || "")
    ? handleBotRequest(
        request,
        responseStatusCode,
        responseHeaders,
        remixContext
      )
    : handleBrowserRequest(
        request,
        responseStatusCode,
        responseHeaders,
        remixContext
      );
}

function handleBotRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  return new Promise((resolve, reject) => {
    let shellRendered = false;
    const { pipe, abort } = renderToPipeableStream(
      <RemixServer
        context={remixContext}
        url={request.url}
        abortDelay={ABORT_DELAY}
      />,
      {
        onAllReady() {
          shellRendered = true;
          const body = new PassThrough();
          const stream = createReadableStreamFromReadable(body);

          responseHeaders.set("Content-Type", "text/html");

          resolve(
            new Response(stream, {
              headers: responseHeaders,
              status: responseStatusCode,
            })
          );

          pipe(body);
        },
        onShellError(error: unknown) {
          reject(error);
        },
        onError(error: unknown) {
          responseStatusCode = 500;
          // Log streaming rendering errors from inside the shell.  Don't log
          // errors encountered during initial shell rendering since they'll
          // reject and get logged in handleDocumentRequest.
          if (shellRendered) {
            console.error(error);
          }
        },
      }
    );

    setTimeout(abort, ABORT_DELAY);
  });
}

function handleBrowserRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  return new Promise((resolve, reject) => {
    let shellRendered = false;
    const { pipe, abort } = renderToPipeableStream(
      <MuiProvider>
        <RemixServer
          context={remixContext}
          url={request.url}
          abortDelay={ABORT_DELAY}
        />
      </MuiProvider>,
      {
        onShellReady() {
          shellRendered = true;
          const body = new PassThrough();
          const stream = createReadableStreamFromReadable(body);

          responseHeaders.set("Content-Type", "text/html");

          resolve(
            new Response(stream, {
              headers: responseHeaders,
              status: responseStatusCode,
            })
          );

          pipe(body);
        },
        onShellError(error: unknown) {
          reject(error);
        },
        onError(error: unknown) {
          responseStatusCode = 500;
          // Log streaming rendering errors from inside the shell.  Don't log
          // errors encountered during initial shell rendering since they'll
          // reject and get logged in handleDocumentRequest.
          if (shellRendered) {
            console.error(error);
          }
        },
      }
    );

    setTimeout(abort, ABORT_DELAY);
  });
}

主要用了 ThemeProvider,有了 ThemeProvider,Theme的配置就可以传递到组件了。完整的项目,可以访问 git https://github.com/sjwan/remix-mui。

项目中用加了 meta theme-color,有了这个主题颜色,浏览器的整体颜色就会一起变化,IOS 15 以上的系统浏览器 Safari 支持这个效果,macos 并不支持。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1669397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现字符串复制(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 0;char a[100], b[100];//获取字符串&#xff1b;printf("请为数组a输入字符串…

如何在外网访问内网共享文件?

在日常工作和生活中&#xff0c;我们经常会遇到外网访问内网共享文件的需求。我们可能需要远程访问公司内部的共享文件夹&#xff0c;或者与不同地区的合作伙伴共享文件。由于网络安全的限制&#xff0c;外网访问内网的共享文件并不是一件容易的事情。 为了解决这个问题&#x…

java项目之车辆管理系统(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的车辆管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 车辆管理系统的主要使用者分…

Python 旋转立方体

文章目录 效果图运行环境完整代码实现思路1. 导入库和定义常量2. 创建Cube类3. 实现Cube类的draw方法4. 实现主函数 效果图 运行环境 python版本&#xff1a;python3.x 依赖包&#xff1a; $ pip install pygame $ pip install numpy完整代码 import numpy as np # 导入 N…

【YOLOv8模型网络结构图理解】

YOLOv8模型网络结构图理解 1 YOLOv8的yaml配置文件2 YOLOv8网络结构2.1 Conv2.2 C3与C2f2.3 SPPF2.4 Upsample2.5 Detect层 1 YOLOv8的yaml配置文件 YOLOv8的配置文件定义了模型的关键参数和结构&#xff0c;包括类别数、模型尺寸、骨干&#xff08;backbone&#xff09;和头部…

单调栈问题

原理 单调栈的核心原理是&#xff1a;在栈内保持元素的单调性&#xff08;递增或递减&#xff09; 单调递增栈&#xff1a; 用于处理“下一个更小的元素”问题。当新元素比栈顶元素小或等于时&#xff0c;直接入栈&#xff1b;否则&#xff0c;一直从栈顶弹出元素&#xff0c…

会声会影2024中文汉化补丁器附免费激活码序列号

会声会影是一款由加拿大Corel公司发布的视频编辑软件&#xff0c;它以其功能丰富和用户友好的界面而闻名。会声会影2024是该系列的最新版本&#xff0c;它不仅继承了之前版本的强大功能&#xff0c;还引入了一系列新的特性和工具&#xff0c;使得视频编辑更加简单、高效且富有创…

【简单讲解下Fine-tuning BERT】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

TCP 重传、滑动窗口、流量控制、拥塞控制 TCP 重传超时重传快速重传 滑动窗口流量控制拥塞控制慢启动拥塞避免拥塞发生快速恢复 TCP 重传 TCP重传是当发送的报文发生丢失的时候&#xff0c;重新发送丢失报文的一种机制&#xff0c;它是保证TCP协议可靠性的一种机制。 TCP重传…

【Oracle篇】rman物理备份工具的基础理论概述(第一篇,总共八篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…

试衣不再有界:Tunnel Try-on开启视频试衣应用新纪元

论文&#xff1a;https://arxiv.org/pdf/2404.17571 主页&#xff1a;https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要总结 随着虚拟试衣技术的发展&#xff0c;消费者和时尚行业对于能够在视频中实现高质量虚拟试衣的需求日益增长。这项技术允许用户在不实际穿…

云计算十三课

centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统&#xff0c;下一步 选择Linux&#xff08;l&#xff09;下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文&#xff0c;点击确定 点击下一步 设置磁盘大小点击下一步…

修改MTU值解决Linux下运行top命令卡死问题

上周明月的Linux服务器上运行top命令总是莫名的出现卡死现象&#xff0c;甚至是CtrlC都无法终止进程&#xff0c;今天终于抽空找到了解决办法&#xff0c;原来是需要修改Linux的MTU值&#xff0c;将服务器操作系统数据包调小&#xff0c;加上VxLAN数据包小于1500即可。 top命令…

HCIP【BGP综合实验】

目录 一、实验拓扑图&#xff1a; 二、实验要求&#xff1a; 三、实验思路&#xff1a; 四、实验步骤&#xff1a; 1、进行网段的子网划分&#xff08;整个实验总共有19条网段&#xff09;&#xff1a; (1)首先&#xff0c;根据实验要求&#xff0c;将172.16.0.0/16全部划…

英伟达发布AM-RADIO高效视觉基础模型,推理速度提升6倍,性能超CLIP、DINOv2、SAM

前言 近年来&#xff0c;视觉基础模型 (VFM) 在众多下游任务中取得了巨大成功&#xff0c;例如图像分类、目标检测和图像生成等。然而&#xff0c;现有的 VFM 通常专注于特定领域&#xff0c;例如 CLIP 擅长零样本视觉语言理解&#xff0c;DINOv2 擅长语义分割&#xff0c;SAM…

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

C++内存管理new/delete和new[ ]/delete[ ]

1.c/c内存分布 首先看一段代码 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd";const char* pChar3 "abcd"; //这里不加const会导致…

整理好的宁夏光伏发电数据集(2007-2020年)

1、包含指标&#xff1a;采样结束时刻、采样起始时刻、时间间隔、气温、方位角、云层不透明度、露点温度、DHI&#xff08;太阳散射辐射指数&#xff09;、DNI&#xff08;太阳直接辐射指数&#xff09;、GHI&#xff08;太阳总水平辐射&#xff09;、GTI&#xff08;固定倾角辐…

06-Fortran基础--Fortran模块化编程

06-Fortran基础--Fortran模块化编程 1 模块的定义和使用2 接口和模块间通信3 模块化编程的优势&#xff1a;4 模块使用示例5 结语 Fortran的模块化编程是一种组织和管理代码的方法&#xff0c;它包括模块的定义和使用、接口和模块间通信以及模块化编程的优势。 1 模块的定义和…

外网如何访问内网?快解析

由于公网IP资源短缺&#xff0c;我们的电脑大多处于内网环境&#xff0c;如何在外网访问内网电脑&#xff0c;成为一个令人头疼的问题&#xff0c;下面我给大家推荐一个非常实用的方法。 1&#xff1a;访问快解析下载安装快解析服务器 2&#xff1a;运行软件&#xff0c;点击“…