Skip to content

Why my view doesn't update?

If you start working with Unistyles 3.0, it might be unclear why some views are updated while others aren’t. Before diving into this guide, make sure you’ve read the other guides covering the basics of the new Unistyles:

To leverage ShadowTree updates and avoid unnecessary re-renders, Unistyles must process both StyleSheets and your components. The Babel plugin processes:

  • every file under the required root folder (no matter what it imports)
  • files outside of root that create a StyleSheet from Unistyles or import one of the autoProcessImports paths

Files inside node_modules are ignored, unless they match autoProcessPaths.

Views usually stop updating when a component lives outside of root (e.g. in a shared monorepo package) in a file that doesn’t create its own StyleSheet (for example, it imports styles from another file), or inside a 3rd party library. For such cases, use the autoProcessPaths, autoProcessImports or autoRemapImports options. Be sure to check them out.

Unistyles will automatically detect all your dependencies for every StyleSheet, but there’s a chance you used custom syntax that isn’t covered by the plugin. If Babel fails to detect some style dependencies, they won’t be updated when necessary.

You can easily debug this issue by adding the following Babel plugin configuration:

babel.config.js
module.exports = function (api) {
api.cache(true)
return {
// other config
plugins: [
// other plugins
['react-native-unistyles/plugin', {
root: 'src',
debug: true // add this option
}]
]
}
}

Then, restart the Metro server cache and check the console, where you’ll find every file and style with its detected dependencies.

Unistyles can only update React Native components. If you’re using a third-party component, you’ll need to apply a different strategy. Follow our decision algorithm to help you choose the best approach.

This issue indicates that the Babel plugin didn’t detect some of your components. Initially, it may seem like native styles are working correctly, but that’s not the case.

On mobile, styles are returned the same way as in React Native. You can always console.log them to inspect the parsed values:

mobile
export const MyView: React.FunctionComponent = () => {
console.log(styles.container) // { backgroundColor: 'red', unistyles_xyz: {} }
return (
...
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'red'
}
})

For the web, styles are not returned directly, as they are converted into CSS classes. If you try to log them, you won’t see any style values:

web
export const MyView: React.FunctionComponent = () => {
console.log(styles.container) // { unistyles_xyz: {} }
return (
...
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'red'
}
})

That’s why you might mistakenly think the problem is only on the web. Please follow the Babel config to ensure all your components and StyleSheets are detected correctly.

Screens can be hidden without being unmounted, for example:

  • with freezeOnBlur in react-navigation / react-native-screens (powered by react-freeze, which uses Suspense)
  • with the inactiveBehavior option in react-navigation (powered by React’s <Activity />)
  • by a Suspense boundary showing its fallback

Unistyles keeps the bindings of such views. Theme and runtime changes made while a screen is hidden are applied when the screen becomes visible again.

Components that use useUnistyles or withUnistyles re-render only after the screen is unfrozen, as React blocks rendering of frozen trees.