I have the next component:
const App = observer(({injector}: Props) => { const preferences = injector.getPreferences().execute() const themeStore = useLocalStore(() => ({ _theme: preferences.theme === ETheme.DARK ? CombinedDarkTheme : CombinedDefaultTheme, get theme(): ReactNativePaper.Theme & Theme { return this._theme }, set theme(value: ReactNativePaper.Theme & Theme) { this._theme = value }, })) const onThemeChange = React.useCallback(() => { const colorScheme = Appearance.getColorScheme() themeStore.theme = colorScheme === 'dark' ? CombinedDarkTheme : CombinedDefaultTheme }, [themeStore]) React.useEffect(() => { if (preferences.theme === ETheme.SYSTEM) { const subscription = Appearance.addChangeListener(onThemeChange) return subscription.remove } }, [onThemeChange, preferences.theme]) return (<PaperProvider theme={themeStore.theme}><NavigationContainer theme={themeStore.theme}> // Some views</NavigationContainer></PaperProvider> )})
Global MobX store:
export default class PreferencesGateway implements IPreferencesGateway { _preferences: Preferences = { theme: ETheme.LIGHT, signedInUserId: null, } constructor(private _storage: IStorageGateway) { makeObservable(this, { _preferences: observable, preferences: computed, setPreferences: action, }) } get preferences(): Preferences { return this._preferences } async setPreferences({ theme, signedInUserId, }: PreferencesUpdate): Promise<void> { if (theme) this._preferences.theme = theme if (signedInUserId !== undefined) this._preferences.signedInUserId = signedInUserId await this.savePersistData() } async loadPersistData(): Promise<Preferences> { const prefs = await this._storage.get<Preferences>(STORAGE_KEY_PREFERENCES) if (prefs) this._preferences = prefs return this._preferences } async savePersistData(): Promise<void> { await this._storage.set(STORAGE_KEY_PREFERENCES, this._preferences) }}
I need to App
listened MobX global store (preferences.theme
), the ETheme
definition is below:
enum ETheme { DARK = 'DARK', LIGHT = 'LIGHT', SYSTEM = 'SYSTEM',}
When the user sets preference.theme
to DARK
or LIGHT
, the app just follows a simple expression:
theme = preferences.theme === ETheme.DARK ? ETheme.DARK : ETheme.LIGHT
However, when user sets preference.theme
to AUTO
, the app has to subscribe on Appearance.addChangeListener()
and follows a system theme.
Unfortunately, my solution doesn't work correctly and leads to multiple changes when the user sets AUTO
. I am a noobie in React Native and MobX and can't get an error reason but seems these stores conflict. I've also tried useState
instead of useLocalStore
but it just led to infinite redrawing.
How to fix it?
P.S. I feel that I've written a some bul****, and it can be simplified also.