When StyleProvider theme is changed it does not get propagated to the ConnectedComponents(components that are decorated with connectStyle). After some debugging I found this issue is due to a bug in native-base-shoutem-theme connectStyle.js, specifically getOrSetStylesInCache method.
```
getOrSetStylesInCache(context, props, styleNames, path) {
if (themeCache && themeCache[path.join('>')]) {
// console.log('****');
return themeCache[path.join('>')];
} else {
resolvedStyle = this.resolveStyle(context, props, styleNames);
if (Object.keys(themeCache).length < 10000) {
themeCache[path.join('>')] = resolvedStyle;
}
return resolvedStyle;
}
}
Looks like it is using the cached version of the theme for current component. The fix is to
remove the if block that is looking for the cached version of the style for the current component. The cache is still used for lookup of parent styles.
getOrSetStylesInCache(context, props, styleNames, path) {
resolvedStyle = this.resolveStyle(context, props, styleNames);
if (Object.keys(themeCache).length < 10000) {
themeCache[path.join('>')] = resolvedStyle;
}
return resolvedStyle;
}
```
I have a sample code to demonstrate this issue Github repo
I tried this and I noticed the theme still doesn't update if it's inside a react-navigation navigator. Do you have any idea why this could be?
@Talor-A I use react-native-navigation and have no experience with react-navigation. Could you create a sample project without react-navigation to confirm whether the fix works?
@SupriyaKalghatgi Any update on this?
@himanshu-satija Any update on this? I have sent a pull request for this
Any update on this ???
Same problem for me! header background doesn't update! Any fix about that?
Hey guys,
Looks like this cache is also an issue for hot reloading of a component styles. Do you plan to add api to somehow invalidate the cache?
This problem still ocurrs, having the same trouble here. Any plans for a new release of native-base with a new version of native-base-shoutem-theme containing @Micjoyce PR Add function to clear the theme cache #5 ?
@SupriyaKalghatgi Can you apply this solution about clean the cache?
Because in this case the control of cache is the developer responsibility.
It's a better solution in this moment, please reconsider it.
Thanks :D
No answer since July.
Did anyone found a workaround ? I am trying to switch between two themes.
I'd like to support a night mode in our app. I have a day theme and a night theme. Switching themes at runtime does not invalidate the theme cache so any components using connectStyle don't update. I think that's a valid use case for being able to switch themes at runtime.
Also experiencing this issue in a react-native app using react-navigation. Any chance anyone is working on or has found a fix?
I'm using a switch navigator like this:
const App = createSwitchNavigator(
{
AuthLoading: AuthLoadingComponent,
App: AppStack,
Auth: AuthStack
},
{
initialRouteName: "AuthLoading"
}
);
And via redux, I merge my theme properties with a custom theme (mostly colors) for certain parts of my app.
render() {
let mergedTheme = variables;
if (this.props.theme === "WO") {
mergedTheme = Object.assign(variables, woVariables);
} else if (this.props.theme === "C") {
mergedTheme = Object.assign(variables, cVariables);
}
return (
<Root>
<StyleProvider style={getTheme(mergedTheme)}>
<App
ref={navigatorRef => {
navigationService.setTopLevelNavigator(navigatorRef);
}}
/>
</StyleProvider>
</Root>
);
}
The behavior is unpredictable. It doesn't generally work, but on some navigation events it will switch to the merged theme and then stick there (i.e. in the AuthStack but not AppStack). I am not sure if this is something wrong with react-navigation or this library but it seems there are a lot of issues using the two together.
Any advice is appreciated.
Did anyone manage to get this to work? Is it possible to update the theme on the fly by just passing a new style object to the provider? This would be similar to the material-ui library for react web... where you can easily switch themes on the fly, re-render the root, and voila!
Need this pull request for this to be fixed: https://github.com/GeekyAnts/theme/pull/5
Any updates? Is this library still maintained? It's a very small PR that would save people from monkey patching the library...
I, too, have encountered this issue now. Seeing the age of this request makes me weary on relying on NativeBase in any of my projects.
I'd love to see this fixed! 馃槃
Hi, here is a workaround that worked for me. It is not perfect because the app is reset to its initial screen, but the new theme gets applied atleast. I am also using react-navigation. The important parts are to call clearThemeCache() when the theme will get changed and change the key prop on the StyleProvider.
import React, {Component} from 'react';
import {StyleProvider} from 'native-base';
import { clearThemeCache } from 'native-base-shoutem-theme';
import getTheme from '../styles/native-base-theme/components';
import Themes from '../styles/native-base-theme/variables/themes';
export default class StyleWrapper extends Component {
constructor(props){
super(props);
this.state = {
'themeName': 'light'
};
this.timer = false;
}
componentDidMount(){
this._switchTheme();
}
_switchTheme = () => {
this.timer = setTimeout(() => {
// The clearThemeCache() must be called
clearThemeCache();
const themeName = this.state.themeName == 'light' ? 'dark' : 'light';
this.setState({themeName});
this._switchTheme();
}, 10000);
}
componentWillUnmount(){
clearTimeout(this.timer);
}
render() {
const { themeName } = this.state;
console.log('Theme changed', themeName, Themes[themeName].toolbarDefaultBg);
// Note the key prop on StyleProvider, it is required to make the code work
return (
<StyleProvider style={getTheme(Themes[themeName])} key={ themeName }>
{this.props.children}
</StyleProvider>
);
}
}
Most helpful comment
@SupriyaKalghatgi Can you apply this solution about clean the cache?
Because in this case the control of cache is the developer responsibility.
It's a better solution in this moment, please reconsider it.
Thanks :D