Repository navigation
fix(native): warn about a re-mount exactly when the element re-mounts - #469
Open
YevheniiKotyrlo wants to merge 1 commit into
Open
YevheniiKotyrlo wants to merge 1 commit into
YevheniiKotyrlo wants to merge 1 commit into
Conversation
YevheniiKotyrlo
force-pushed
the
fix/remount-warning-matches-remount
branch
from
October 6, 2026 10:05
72bf741 to
8e8bef0
Compare
The warning compared each class prop's partial state inside the loop, so it fired on renders that re-mount nothing and stayed silent on some that do. It now compares the derived state on the four fields useNativeCss picks the element's wrappers from. `will-change-pressable` marks an :active rule, which is what keeps an element a Pressable, and an onPress arriving or leaving re-derives the rules.
YevheniiKotyrlo
force-pushed
the
fix/remount-warning-matches-remount
branch
from
October 11, 2026 12:35
8e8bef0 to
601f97a
Compare
This was referenced Oct 11, 2026
Open
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
useNativeCssre-mounts an element only when the state it renders from changes its wrappers or its animated component, or swaps aViewfor aPressable.updateRulesdecides whether to warn about a re-mount inside its loop over the element's className props, from what that loop has accumulated so far. That check disagrees with the re-mount in four ways:ScrollView'sclassNameandcontentContainerClassName) compares the first prop's partial result. A scope that never changed logsclassName 'undefined' added or removed a variable, and a real change logs once per prop.vars()is merged into the variables after the check, so an element that keeps them logs on mount and on every re-render.Viewis swapped for aPressable. Yet the pressable warning is logged by aTextor aScrollViewthat gains an:activerule, and by aViewwhose ownonPressalready made it aPressable. AViewwhose ownonPresscomes or goes is re-mounted with no warning, becauseonPressis not a render guard.will-change-pressableregisters:hover(p: { h: 1 }), so aViewcarrying it is still swapped, and re-mounted, when an:activerule arrives.Solution
updateRulesderives the next state first and compares it with the state it was given, so the warning reads the same fieldsuseNativeCssrenders from.contentContainerClassName 'my-padding').pressableundefined, as its initial state already encodes.Viewgets a presence guard ononPress, so the swap is seen whichever side causes it. The guard is a"p"guard, which re-derives whenonPresscomes or goes and not when its identity changes.will-change-pressableregisters:active.Tests
Every case renders a child that counts its mounts, so each assertion compares the warnings with a re-mount that was observed:
ScrollViewwith a variable, a colour, a container and an animation rule, each on either className prop:inlineVariables: false: the padding resolves the same, and the element warns and re-mounts only when the compiled rule carries a variable, read from the compiler's output.Pressableswap::activerulewill-change-pressableView's ownonPressarriving, leaving or already thereTextand aScrollView, which are never swappedwill-change-variable,-containerand-animationon one className prop keep the element from re-mounting when the rule arrives on the other.vars()onstyleand oncontentContainerStyle, invars.test.tsx.On
main, 80 of the 107 cases in the two files fail; all pass here. Eight mutations each fail their own cases:will-change-pressableregistering:hoveronPresspresence guardonPressVerification
On Windows with Node 26:
yarn lintcleanyarn typecheckcleanyarn test --maxWorkers=2 --coverage: 1435 passed, 4 failed. The 4 are the babel cases that also fail onmainon this machine.yarn buildcleanyarn example expo export --platform webexportedNo existing issue tracks this. I searched for
added or removed a variable,will-change-variable,will-change-pressable,re-mounted,contentContainerClassNameandremount warning. nativewind/nativewind#1646 reports this warning on a class change but has no reproduction, so I can't tell whether it is one of these cases.Merge order
This overlaps #391; I'll re-cut whichever of the two lands second.
It also shares lines with #412 (
__tests__/native/vars.test.tsx,native/react/rules.ts), #423 (__tests__/native/vars.test.tsx), #431 (__tests__/native/vars.test.tsx), #436 (native-internal/style-collection.ts), #443 (__tests__/native/vars.test.tsx); whichever lands second rebases.Base
Re-written on
main(a5002c5).