Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

varResolver: a var() resolved from the :root/inline/universal fallback isn't guarded — a token provided via context after first render never re-resolves

Đang mở
#377 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 3 ngày

@huytdps13400 đang làm issue này rồi.

Từ ngày 3/10/2026.

  • #467 của @huytdps13400 — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
react, react-native, typescript
Lĩnh vực
frontend, mobile

Hướng nghiên cứu

Start in src/native/styles/variables.ts, in varResolver, and compare the name in variables branch, which pushes a guard, with the fallback path after variableHistory.add(name), which does not. Linked PR #467 is already open against this, so check it before writing anything. Done means a test where a var() resolves from :root, a VariableContextProvider then supplies the token, and the mounted node re-resolves.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

auto-triaged bug confirmed

Summary

In varResolver (src/native/styles/variables.ts), a re-render dependency guard is recorded only on the name in variables (inherited VariableContext) path. When a var() is instead resolved from the inline / universal / :root fallback, the function returns without pushing a guard. As a result, a token that is absent from context at first render (so it resolves from :root) and is later provided via a nearer VariableContextProvider is never re-resolved on an already-mounted node — the node stays at the :root/fallback value permanently.

It's timing-sensitive: it only manifests when the context value arrives after the first paint of the consuming node. On a fast first paint the token is already in context (guarded → works); on a slower first paint (e.g. Android/Hermes committing before an async provider updates) the node latches the fallback value forever.

Version

[email protected]

Repro

A styled/useCssElement node whose var(--x) starts unset (resolves from :root) and is later given a value via a VariableContextProvider higher in the tree keeps the :root value — it never re-resolves when --x subsequently appears in context.

Concretely: render a node using var(--brand) where --brand is not yet provided by any context; later push --brand into a VariableContextProvider. The mounted node keeps the :root/fallback value instead of updating.

Root cause

varResolver pushes renderGuards.push(["v", name, variables[name]]) inside the if (name in variables) { … } branch and then returns. The other path — reached when name is not in variables (it runs variableHistory.add(name) and then the inline → universal → :root → fallback lookups) — returns without recording any guard for name. So testGuards watches nothing for that token, and a later context change for it never triggers re-resolution of the mounted node.

Proposed fix

Record a guard for the "currently absent from context" state as well — push renderGuards.push(["v", name, variables[name]]) immediately after variableHistory.add(name) (before the fallback lookups). variables[name] is undefined there, which is the correct sentinel: the guard then fires precisely when the token later appears in context, and there is no value shadow (the returned value is still the :root/fallback until context provides one). It terminates cleanly — exactly one extra re-resolve on the absent→present transition.

Context

We hit this in a production React Native app where channel/brand CSS variables are supplied asynchronously (fetched, then injected as a delta over the :root defaults). iOS happened to paint after the fetch (token in context → guarded → correct); Android painted before it and latched the default. We're currently carrying a local patch that applies the one-line fix above; filing upstream so it can live in the library. Happy to open a PR if that's useful.

(Distinct from #245, which is about a memory leak on re-render.)

Ngôn ngữ chính
TypeScript
Star
166
Fork
45
Merge trung bình
13 ngày 14 giờ
Pull request đã merge (30 ngày)
1

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nativewind/react-native-css

Tất cả issue của nativewind/react-native-css

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.