microsoft / fluentui-react-native

A react-native component library that implements the Fluent Design System.

Home Page:https://developer.microsoft.com/fluentui

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ThemeProvider not updating the state when themeRef changes

imbaky opened this issue · comments

Willing to submit a PR to fix?

  • I am willing to submit a PR to fix

Requested priority

High

Products/applications affected

No response

Package version(s)

@fluentui-react-native/theme": "^0.9.1

OS version(s)

No response

Platform

  • iOS
  • macOS
  • win32
  • windows
  • android

Xcode version

No response

Please provide a reproduction of the bug

If you have a code similar to the one below which can change the themeRef passed to the themeProvider:

render(){

  let currentThemeRef = useMemo(()=>{

    return defaultTheme ? new ThemeReference(defaultFluentTheme) :  new ThemeReference(defaultFluentTheme, ()=>{
                 return {colors: {  background: '#f8b0b0' /* pink */,} };
      });
  }, [props.Theme]);


return (
<ThemeProvider theme={currentThemeRef}>
           <Button />
<ThemeProvider>
);

}

Actual behavior

When the themeRef changes the ThemeProvider state doesn't change.

export const ThemeProvider: React.FunctionComponent<ThemeProviderProps> = (props: ThemeProviderProps) => {
  const { theme: themeRef, children } = props;
  const [theme, setThemeState] = React.useState(() => themeRef.theme);

  React.useEffect(() => {
    const onInvalidate = () => {
      setThemeState(themeRef.theme);
    };

    themeRef.addOnThemeChanged(onInvalidate);
    return () => {
      themeRef.removeOnThemeChanged(onInvalidate);
    };
  }, [themeRef, setThemeState]);

Expected behavior

When the themeRef changes the ThemeProvider state should change.

Proposed fix:

export const ThemeProvider: React.FunctionComponent<ThemeProviderProps> = (props: ThemeProviderProps) => {
  const { theme: themeRef, children } = props;
  const [theme, setThemeState] = React.useState(() => themeRef.theme);

  React.useEffect(() => {

    // Proposed fix
    setThemeState(themeRef.theme);

    const onInvalidate = () => {
      setThemeState(themeRef.theme);
    };

    themeRef.addOnThemeChanged(onInvalidate);
    return () => {
      themeRef.removeOnThemeChanged(onInvalidate);
    };
  }, [themeRef, setThemeState]);

The issue was created and being tracked on ADO in the Fluent path.

#3370 should fix this. I will close this out for now.