I'd like to introduce a simple configurable theme to my (expo augmented) react-native app, with initial focus on the background color. I've had some success implementing the dynamic aspects, e.g. the user can pick a theme/background color in the app, and the color affects all the screens. I used a fairly typical techinique where the App.js wraps its (V5) NavigationContainer and its theme in a Context provider, e.g.
return (
<SomeProvider>
<NavigationContainer theme={AppDefaultTheme} ref={navigationRef}>
... stuff including navigators
<NavigationContainer>
</SomeProvider>
)
On the component side we can retrieve the theme (initially the default) using the useTheme hook, then change the background or whatever, and (temporarily) persist the mutated theme to state in the Provider's reducer. The reducer can also persist the mutated theme to something like AsyncStorage for the next application start.
The application restart is where the problem comes in.
There seems to be no way to retrieve the current theme from cold storage (AsyncStorage or other) in App.js in time to supply it to the NavigationContainer
(remember this)
<NavigationContainer theme={AppDefaultTheme} ref={navigationRef}>
Numerous posts point out that there is no beforeRender hook or capability in RN/expo. And by the time we haul back AppDefaultTheme in a useEffect hook, the App.js NavigationContainer has long since left the station.
I'm guessing that retrieving initial state just isn't possible unless perhaps using an external state manager like Redux. Is Redux how people have solved this problem? I've been very happy with "nonReduxLight", e.g. redux patterns using Provider wrappers per the above, and a color theme feature isn't quite enough to get me to dive into that deep swimming pool, but it's getting close.
Will Redux do what I want? Is there an easier way?