This is useful for libraries like `expo-auth-session` which also use links for authentication.
Usage:
```js
const linking = {
prefixes: ['myapp://'],
filter: (url) => !url.includes('+expo-auth-session'),
};
```
Problem:
When using nested navigators, unmounts cause race cleanup races.
Imagine following hierarchy (from tree root downwards, parent to children):
TabNavigator (1) [renders useNavigationBuilder]
SceneView (from TabNavigator)
StackNavigators (N) [each renders useNavigationBuilder]
SceneView (from StackNavigator)
Now lets test following flow:
1. Mount above navigators with given navigation params (e.g. navigation for unauthenticated users)
2. Unmount all navigators (e.g. during login process)
3. Mount above navigation with different navigation params than in 1) (e.g. navigation for authenticated users)
What you'll observe, there will be old navigation params preserved in 3) coming from 1).
Source of problem:
BaseNavigationContainer holds global navigation state, exposes API to modify it via NavigationStateContext. When useNavigationBuilder unmounts, it attempts to clear navigation state. (see cleanup effect in useNavigationBuilder.tsx).
(I) First clear occurs in TabNavigator's effect, which successfully clears BaseNavigationContainer's state (sets it to undefined).
(II) Second clear comes from StackNavigator unmount. It's useNavigationBuilder cleanup effect also calls NavigationStateContext.setState(undefined).
But this time - we meet SceneView as closest NavigationStateContext.Provider. SceneView attempts to merge state change with current navigation state, which is reasonable. But current navigation state should be already undefined... It is, but:
```
[useNavigationBuilder.tsx]
const getState = React.useCallback((): State => {
const currentState = getCurrentState();
return isStateInitialized(currentState)
? (currentState as State)
: (initializedStateRef.current as State);
}, [getCurrentState, isStateInitialized]);
```
"undefined" state is treated is non-initialized state, and freshly computed state (initializedStateRef.current) is returned instead.
SceneView does merge this old state with `undefined` value, and passes to BaseNavigationContainer. Now we have some legacy global state, despite all navigators being unmounted.
After mounting navigators again (3), we can observe old params being restored. These params might come e.g. from old `initialParams` prop (from 1)).
Solution:
Do not propagate `setState` upwards in `useNavigationBuilder` after state cleanup. This way we'll omit such races.
I noticed that accessing `closing` through `cardStyleInterpolator` would always return an Animated node with value 0. It looks like it isn't being updated anywhere, so I added it to the `animate` method.
I am using this functionality to allow screens to have different in and out transitions.
On a side note, I feel like this would be more useful as a boolean, instead of an Animated value.
Co-authored-by: Michael Ru <michaelru@abridge.com>
This should fix the Netlify builds too.
See here for reference: https://github.com/nvm-sh/nvm#nvmrc
The integration tests are failing but they are getting fixed in #9667.
Hey!
I made the following changes:
- Replaced Jest by the new Playwright test-runner
- Disabled the Jest linting rules for the Playwright e2e tests
- Rewrote the tests to the new test-runner
- Adjusted `Link.test.ts` which should be less flaky
- The tests run now across all three browsers: Chromium, Firefox, and WebKit
See here for reference about the new test-runner: https://playwright.dev/docs/test-intro
I extracted a fix for Netlify in #9668.
Let me know if you have any questions.