Skip to content

Conversation

@pull
Copy link

@pull pull bot commented Jan 30, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

alanjhughes and others added 4 commits January 30, 2026 07:37
…nges (#42681)

# Why

Fixes #35303.

The `<Head>` component from `expo-router/head` doesn't update the
document title correctly on web when using tab navigation. When
navigating away from a tab and returning to it, the title remains stale.
This is due to a combination of factors:

- The [tab navigator caches loaded
screens](https://github.com/react-navigation/react-navigation/blob/7.x/packages/bottom-tabs/src/views/BottomTabView.tsx),
which means they stay mounted when switching tabs
- [`react-helmet-async`'s `HelmetDispatcher` has a `rendered`
flag](https://github.com/expo/expo/blob/8c549621b1fd4b3c425ec97e528ab6edba8e24f0/packages/expo-router/vendor/react-helmet-async/lib/index.esm.js#L635-L637)
that prevents reinitialization on subsequent renders

When returning to a cached tab, the component re-renders but doesn't
remount, which prevents `react-helmet-async` from re-rendering any
`<meta>` tags.

# How

Modified `ExpoHead.tsx` to use a similar pattern as the iOS
implementation, it now conditionally renders based on focus state using
the `isFocused` hook from React Navigation.

# Test Plan

- CI
- Manual testing

# Checklist

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…tability (#42368)

# Why

The `useLoaderData()` hook previously used module-level `Map` caches for
storing loader data, promises, and errors. This made it difficult to
test its behavior in isolation since the cache state persisted across
tests and made it difficult to mock.

# How

- Created a new `LoaderCache` which encapsulates the data, promises and
error maps and provides typed getter/setter methods. This class is then
exposed via a React context called `LoaderCacheContext`
- Created a new `getLoaderData()` function for handling cache lookup and
fetching logic
- Thinned out `useLoaderData()` hook by using the `getLoaderData()`
function
- Modified `renderHook()` test helper to allow wrapping `<ExpoRoot>`
- Added/improved unit/integration tests to cover existing loader
scenarios

# Test Plan

- CI

# Checklist

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
@pull pull bot locked and limited conversation to collaborators Jan 30, 2026
@pull pull bot added the ⤵️ pull label Jan 30, 2026
@pull pull bot merged commit 5e5874a into code:main Jan 30, 2026
23 of 26 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants