自定义脉轮主题加载缓慢

问题描述

在我们的项目中,我们以 AngularJS 为核心,我们正在过渡到 React。在 React 方面,我们使用带有自定义主题的 Chakra UI。

当加载 React 组件时,我们使用自定义主题的 ChakraProvider 包装组件,它看起来像这样:

<DesignProvider>
  <FolderPermissionsIndicator {...props} />
</DesignProvider>

DesignProvider 在哪里:

import { ChakraProvider,ChakraProviderProps } from '@chakra-ui/react';
import * as React from 'react';
import { theme } from './theme';
import { useMemo } from 'react';

export const DesignProvider: React.FC<ChakraProviderProps> = props => {
  const themeInstance = useMemo(() => theme,[]);

  return (
    <div data-ds-next={true}>
      <ChakraProvider resetCSS={false} {...props} theme={themeInstance} />
    </div>
  );
};

主题是:

const theme: ChakraTheme = extendTheme({
  styles: {
    global: {
      ...gigantic object...
    }
  }
});

现在,这很好用,但是如果我们将很多组件嵌入到 AngularJS 中,并且每个组件都分别用 DesignProvider 包裹,事情就会变得很慢。 特别是,合并全球主题定制化需要一些时间。例如,如果我们从主题删除 global 对象,则页面加载一次可能会从大约 20 秒到大约 500 毫秒。

其中一种解决方法当然是将该 global 部分拉入一个 css 文件并全局加载它。不过,这个解决方案有其自身的复杂性。

是否有更简单的方法可以在所有组件之间共享自定义主题

解决方法

Context API 是您问题的解决方案,创建上下文主题,您可以在其中存储主题对象。

来自 React 文档:

上下文旨在共享可被视为“全局”的数据 一棵 React 组件树,例如当前经过身份验证的用户, 主题或首选语言。

主题上下文.js:

import React,{ useState } from 'react';

export const ThemeContext = React.createContext({
  theme :null
});

const ThemeContextProvider = props => {
  const theme: ChakraTheme = extendTheme({
    styles: {
      global: {
        ...gigantic object...
      }
    }
  });
  const [themeState] = useState(theme); 
  return (
    <ThemeContext.Provider
      value={{ theme:  themeState}}
    >
      {props.children}
    </ThemeContext.Provider>
  );
};

export default ThemeContextProvider;

组件设计提供者:

import { ChakraProvider,ChakraProviderProps } from '@chakra-ui/react';
import * as React from 'react';
import { ThemeContext } from './theme-context';
import { useMemo,useContext } from 'react';

export const DesignProvider: React.FC<ChakraProviderProps> = props => {
  const themeInstance = useMemo(() => theme,[]);
  const them = useContext(ThemeContext).theme;

  return (
    <div data-ds-next={true}>
      <ChakraProvider resetCSS={false} {...props} theme={theme} />
    </div>
  );
};

最后一步:使用 ThemeContextProvider 包装您的应用:

<ThemeContextProvider>
  <App/>
</ThemeContextProvider>

因此,每次使用组件 DesignProvider 时,您都不会重用巨型对象,而是会在运行时从 ThemeContext 中获取它们。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...