如何通过情感主题在带样式的组件和插值中实现?

时间:2019-12-09 08:06:40

标签: css reactjs typescript emotion

我一直在使用情绪主题库开发一个具有动态主题的React Web应用程序。因此,用户可以在环境之间切换,并且每个环境都有自己的主题。 我创建了自己的CustomThemeProvider,用于动态更改主题。下面是代码。

export interface CustomThemeContextValue {
    customTheme?: Theme;
    setCustomTheme: (theme: Theme) => void;
};

const CustomThemeContext = React.createContext<CustomThemeContextValue>({
    customTheme: undefined,
    setCustomTheme: (theme) => { }
});

interface CustomThemeProviderProps {

}

export const CustomThemeProvider: FC<CustomThemeProviderProps> = (props) => {
    const [customTheme, setCustomTheme] = useState<Theme>(theme);

    const context: CustomThemeContextValue = React.useMemo(() => ({
        customTheme,
        setCustomTheme
    }), [customTheme, setCustomTheme]);

    return (
        <CustomThemeContext.Provider value={context}>
            <ThemeProvider theme={customTheme} {...props} />
        </CustomThemeContext.Provider>
    );
};

export const useCustomTheme = () => {
    const context = React.useContext(CustomThemeContext);
    if (!context) {
        throw new Error('useCustomTheme must be used within a CustomThemeProvider');
    }

    return context;
};

提供者是像这样在根中实现的

const Root = () => {
    return (
        <StrictMode>
            <CustomThemeProvider>
                <Normalize />
                <Global styles={globalStyle} />
                <App />
            </CustomThemeProvider>
        </StrictMode>
    );
};

因此此代码有效,我可以使用情感useTheme钩子在功能组件中获取主题,如下所示:

const theme: Theme = useTheme();

但是问题是如何从情感ThemeProvider中提取主题并在某些情况下使用它。是否可以在类似

的上下文中使用它
export const style: Interpolation = {
    cssProp: value
};

或者在如下所示的上下文中可用,其中styled.button来自情感/样式。

const Button: FC<HTMLProps<HTMLButtonElement> & ButtonProps> = styled.button([]);

并且可以在情感/核心方法css()中使用吗

const style = css({
    cssProp: value
});

我发现使用Google很难找到这些问题的答案,所以我希望这里的人能帮助我。

1 个答案:

答案 0 :(得分:0)

所以一段时间后,我终于找到了自己的问题的答案,并且我想与所有人分享它,因为很难找到它。所以在这里。

您可以像下面这样使用InterpolationWithTheme来代替插值:

export const style: InterpolationWithTheme<Theme> = (theme) => ({
    cssProp: theme.value
});

这样,您可以从ThemeProvider中获取主题。

使用样式化的组件,您可以像下面这样实现它:

const Button: FC<HTMLProps<HTMLButtonElement> & ButtonProps>
    = styled.button(({ theme }: any) => ([
    {
        cssProp: theme.value
    }
]);

最后,当您要将css()与themeProvider一起使用时,必须将其替换为InterpolationWithTheme,以使其像在此答案的第一个示例中一样起作用。

通过在emotionjs docs中查找并检查情感js类型/界面的组合,可以找到这些答案。