What's Changed
A minor release and the first step towards 4.0: an experimental zero-config Metro integration, faster plain views, Reanimated CSS transitions and iOS gradients that follow theme changes, and a memory leak fix for useVariants.
๐ Experimental Metro integration
- New
react-native-unistyles/metro, a zero-config alternative to the Babel plugin. Wrap your Metro config and removereact-native-unistyles/pluginfrombabel.config.js; there's norootorautoProcessImportsto set. Everyreact-nativeimport, including those innode_modules, resolves to Unistyles components, so third-party components follow theme changes too. The bundle also contains a single copy of Unistyles. The Babel plugin stays the default, and existing setups don't change. Re.Pack, Vite, Next.js and other web bundlers keep using the Babel plugin (#1308, docs)
// metro.config.js
const { getDefaultConfig } = require('expo/metro-config')
const { withUnistylesConfig } = require('react-native-unistyles/metro')
module.exports = withUnistylesConfig(getDefaultConfig(__dirname))โก๏ธ Performance
- Views whose
styleholds no unistyle are no longer linked. Their refs and styles pass through unchanged, with both the Metro integration and the Babel plugin (#1308)
| 3.5.3 | 3.6.0 | |
|---|---|---|
| Plain view re-render | 13.0 | 6.4 |
| Plain view unmount | 5.0 | 1.3 |
Median ms for 900 views, iOS simulator, Release
๐จ Themes and styles
- Reanimated CSS transitions (
transitionProperty) now animate to the new theme's colors after a theme change. Before, they kept the previous theme's colors (#1315, closes #1007) - Fixed views that didn't fully switch themes with Reanimated in the tree, such as nested
Textand variant styles onAnimated.Textafter a breakpoint change (#1315, closes #1170, #1045 and #1142) - Views inside a
Suspensefallback are now refreshed on theme change. Views frozen by react-freeze,Suspenseor a hidden<Activity>that use a CSS transition show the new theme when revealed (#1315)
๐ง Memory
- Fixed a memory leak in
styles.useVariants()when the StyleSheet has a dynamic function. A screen calling it on every render leaked about 270 B per call, e.g. 5.6 โ 13.7 MB after 100 mount cycles. The heap now stays flat (#1323)
๐ iOS
- Gradients from a StyleSheet (
experimental_backgroundImage/backgroundImagestrings) now follow theme changes on React Native 0.83+. Before, a theme change cleared them. On older React Native versions they keep the colors React rendered last (#1319 by @erickreutz, #1320, closes #1030) - With adaptive themes, iOS now follows
Appearance.setColorScheme, like Android (#1304)
๐ค Android
- Flipping
horizontalon aFlatListno longer throws the "detected an unsupported FlatList with the horizontal prop" render error. Flipping it back no longer leaks a registry entry (#1305, closes #803)
๐ Web
- Reanimated's
useAnimatedStylenow works on components wrapped withcreateUnistylesElement. Before, the animated style was silently dropped, so the view never animated (#1201 by @theonetheycallneo, closes #1199) - Breakpoint media queries no longer leave a gap at fractional viewport widths (e.g. 767.5px under browser zoom). Ranges now end at
next โ 0.02px(#1242 by @themikem, closes #1241, docs in #1321)
โ๏ธ React Compiler
- Components calling
styles.useVariants()now compile with React Compiler. Before,panicThreshold: "all_errors"failed the build, and with the default threshold the compiler silently skipped them (#1310, #1311, closes #1002)
๐งช Internal
- An unknown class component ref now resolves to the first native view it renders instead of throwing "Could not find shadow node" (#1315)
โค๏ธ Contributors
Thanks to everyone who sent a PR for this release:
And to those whose PRs and reports shaped the fixes:
- @oblador, @believer, @ilteoood, @saif-o99, @Jonas-Bostoen, @slvvn, @bbbenja for detailed bug reports
Full Changelog: v3.5.3...v3.6.0