-
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use useSyncExternalStore
to sync morfeo's theme with react
#86
Comments
Whenever the
import { morfeo, theme as themeHandler, ThemeName } from '@morfeo/core';
import { useSyncExternalStore } from 'react';
function subscribe(...callback: Parameters<typeof themeHandler.subscribe>) {
const uid = themeHandler.subscribe(...callback);
return () => themeHandler.cleanUp(uid);
}
export function useMorfeo() {
const theme = useSyncExternalStore(subscribe, morfeo.getTheme);
const current = morfeo.getCurrentTheme();
function setCurrent(themeName: ThemeName) {
morfeo.setCurrentTheme(themeName);
}
return { theme, current, setCurrent, subscribe };
} To test if this code is working, I think this simple test would prove the correct behavior: import { renderHook, act } from '@testing-library/react';
import { morfeo, Theme, ThemeName } from '@morfeo/core';
import { useMorfeo } from '../src/useMorfeo';
const LIGHT_THEME = {
colors: {
primary: 'black',
secondary: 'white',
},
} as Theme;
const DARK_THEME = {
colors: {
primary: 'white',
secondary: 'black',
},
} as Theme;
const LIGHT_THEME_KEY = 'light' as ThemeName;
const DARK_THEME_KEY = 'dark' as ThemeName;
beforeAll(() => {
morfeo.setTheme(LIGHT_THEME_KEY, LIGHT_THEME);
morfeo.setTheme(DARK_THEME_KEY, DARK_THEME);
morfeo.setCurrentTheme(LIGHT_THEME_KEY);
});
describe('useMorfeo', () => {
it('should return the theme', () => {
const { result } = renderHook(() => useMorfeo());
expect(result.current.theme).toEqual(LIGHT_THEME);
});
describe('when the theme changes', () => {
it('should return the dark theme', () => {
const { result } = renderHook(() => useMorfeo());
act(() => {
result.current.setCurrent(DARK_THEME_KEY);
});
expect(result.current.theme).toEqual(DARK_THEME);
});
});
}); In case everything works, we should also think about some other changes, for example: MorfeoProviderCurrently, this provider is used to force a re-render when the theme changes, since |
I already tried the snippet in the previous comment and seems to work. Before opening a PR I'll wait for some other updates in other dependencies like |
use `useSyncExternalStore` to sync morfeo with the React render. Removed `MorfeoProvider` / `MorfeoContext` and introduced `useMorfeo` Closes #86
use `useSyncExternalStore` to sync morfeo with the React render. Removed `MorfeoProvider` / `MorfeoContext` and introduced `useMorfeo` Closes #86
use `useSyncExternalStore` to sync morfeo with the React render. Removed `MorfeoProvider` / `MorfeoContext` and introduced `useMorfeo` Closes #86
use `useSyncExternalStore` to sync morfeo with the React render. Removed `MorfeoProvider` / `MorfeoContext` and introduced `useMorfeo` Closes #86
use `useSyncExternalStore` to sync morfeo with the React render. Removed `MorfeoProvider` / `MorfeoContext` and introduced `useMorfeo` Closes #86
Morfeo is born to work everywhere, it already works with
React
,Svelte
,Angular
or any other JS framework. Anyway for any of these framework we usually write packages to make the integration as good as possible, for example withdirectives
for svelte orhook
for react.React v18 introduced a new hook called
useSyncExternalStore
, this hook helps to sync external states with the react state.It seems to be the perfect solution to always be sure that the theme used (and returned) by the hooks or
@morfeo/hooks
is the current used inside themorfeo
instance.It will probably unlock even other functionalities like:
cuncurrent mode
compatibility (not sure it's not working right now)References:
Before proceeding with this issue, we need to upgrade to React 18.
The upgrade to React 18 is covered by this issue
The text was updated successfully, but these errors were encountered: