React native 0.78 compatibility
Describe the bug Hi,
I'm in the process of migrating to React Native 0.78.0 and React 19, and there appear to be compatibility issues with the library in version 5.1.1.
To Reproduce
import {Directions, SpatialNavigation} from 'react-tv-space-navigation';
import {LoggerService} from './logger.service.ts';
import {remoteControlService} from './remote-control.service.ts';
import {SupportedKeysEnum} from '../model/enums/supported-keys.enum.ts';
export class SpatialNavigationService {
private constructor() {
}
public static init(): void {
SpatialNavigation.configureRemoteControl({
remoteControlSubscriber: (callback) => {
const mapping: { [key in SupportedKeysEnum]: Directions | null } = {
[SupportedKeysEnum.Right]: Directions.RIGHT,
[SupportedKeysEnum.Left]: Directions.LEFT,
[SupportedKeysEnum.Up]: Directions.UP,
[SupportedKeysEnum.Down]: Directions.DOWN,
[SupportedKeysEnum.Enter]: Directions.ENTER,
[SupportedKeysEnum.Back]: null
};
const remoteControlListener = (keyEvent: SupportedKeysEnum): void => callback(mapping[keyEvent]);
return remoteControlService.addKeydownListener(remoteControlListener);
},
remoteControlUnsubscriber: (remoteControlListener): void => {
remoteControlService.removeKeydownListener(remoteControlListener);
},
});
LoggerService.info(`[SpatialNavigationService] Initialized spatial navigation service on TV`);
}
}
<SpatialNavigationDeviceTypeProvider>
<SpatialNavigationRoot isActive={true}>
<SpatialNavigationView direction='vertical' style={styles.container}>
<MyAppComponent/>
</SpatialNavigationView>
</SpatialNavigationRoot>
</SpatialNavigationDeviceTypeProvider>
Expected behavior Application continues to work as it normally did in previous versions of React native (in my case 0.76.5).
Screenshots
Version and OS
- Library version: 5.1.1
- React Native version: 0.78.0
- OS: Android
Additional context Add any other context about the problem here.
Hi @pierpo, any update about this?
Hi @pierpo any update on this ?
@pierpo - Any update on this, We are having issue with RN version 0.78, I'm in the process of migrating to React Native 0.78.0 and React 19, and there appear to be compatibility issues with the library.
Hey! Sorry for not being very active on the project right now π Could you help with the investigation? I do not have any time to look at it myself π I'll make some time to review PRs and publish changes, but it would be lovely to get some help regarding the solution!
@pierpo , The React and React-dom version seem to cause this issue. Since the latest version of expo and react-native are using version 19 and SpatialNavigation is using 18.
"@types/react": "~18.2.79", "@types/react-dom": "~18.2.25",
@pierpo Just made a PR for this. Everything is building fine but the mapping of the remote control inst working now. Why i dont know.
https://github.com/bamlab/react-tv-space-navigation/pull/185
Awesome @robmim π I will have a look! Sorry about the very long delay, I was off the whole month!
Any update on this @robmim @pierpo ?
@fuecco I strongly recommend you to use react-native-tv-os instead of this librairy if you need to go forward with your project.
There is plenty of demo and sample project you can based your project on.
https://github.com/react-native-tvos/react-native-tvos/wiki
Any reason for not recommending this library? Do you see any issues/shortcomings?
I'm simply saying that if you need to go forward you should think about using something else. Putting pressure on Pierre or me to fix issues you have doesn't help anyone here. If you want to contribute and help us you are more than welcome to edit code, add pr, find bugs.
@fuecco maybe have a look to this one too. Just found that and really thinking about trying it myself
https://github.com/NoriginMedia/Norigin-Spatial-Navigation
Sorry it's taking so long. I'll try to merge the recent React support this week!
just started setting up new project and ran into this issue at first run !!! @robmim any documentation on how to switch from this package to "react-native-tv-os"
I published v6.0.0-beta1 to unblock you. You might give it a try. I can't merge my PR yet because tests are broken for now π€ (for dependencies issues reasons, not features being broken)
I finally merged the PR, but I'd still like a bit of feedback on the beta before publishing this as 6.0.0 π
https://github.com/bamlab/react-tv-space-navigation/pull/200
@pierpo still on vacation until monday. Will have a look when i will be back
It is working for me on Android, but not on Web. The error is generated by the SpatialNavigationScrollView component
Hey @lKinderBueno, do you have more details to reproduce or a piece of code? Web is working fine on the lib example with the upgrade merged π€
@pierpo I used your example. The only changes are:
- Added missing dependencies in package.json
- Updated imports to point to react-tv-space-navigation instead of the local file path
(ex. from
import { SpatialNavigationVirtualizedListRef } from '../../../../../lib/src/spatial-navigation/types/SpatialNavigationVirtualizedListRef';toimport { SpatialNavigationVirtualizedListRef } from 'react-tv-space-navigation'; - Remove most of the images from modules folder (github limits the upload to max 20MB. The zip was larger than 30)
The zip contains two package.json variants:
- package-5.2.0.json
- package-6.0.0.json
To run the example with Reactβ―native 18 and react-tv-space-navigation v5.2.0:
- Rename package-5.2.0.json to package.json.
- Run
npm install --legacy-peer-deps - Start with
npx expo start --clear - Then press "w" to open the web version
For the 6.0.0 version, just rename package-6.0.0.json to package.json and repeat the same commands. For the 6.0.0 version, the browser should display a blank image with the error reported in previous message. The 5.2.0 version works correctly.
You can grab everything here: test.zip
Salut @pierpo π
I can confirm that similar to @lKinderBueno - Although v6.0.0-beta1 seems to be a great step towards React 19 support by fixing error Cannot read properties of undefined (reading 'ReactCurrentOwner').
There still seems to be some incompatibility when using components <SpatialNavigationScrollView /> and <SpatialNavigationVirtualizedList /> that cause the following error:
Cannot read properties of undefined (reading 'validated')
Thank you for the great package!
Thanks both of you. I need to investigate this then! Any help is appreciated, I know this is a blocker for the library π
Bonsoir @pierpo π
After quite a bit of digging, I noticed a few things:
(1) Since the error happens when using <SpatialNavigationScrollView /> and <SpatialNavigationVirtualizedList /> I tried to find a pattern and noticed that both were using the same context.
(2) The context (SpatialNavigatorParentScrollContext) at packages/lib/spatial-navigation/context/ParentScrollContext.ts was initializing with an empty default value of () => {}
(3) I changed the default value to undefined and setup an error if the context was attempted to be used outside the provider:
export const SpatialNavigatorParentScrollContext = createContext<ScrollToNodeCallback | undefined>(undefined);
export const useSpatialNavigatorParentScroll = (): { scrollToNodeIfNeeded: ScrollToNodeCallback } => {
const scrollToNodeIfNeeded = useContext(SpatialNavigatorParentScrollContext);
if (!scrollToNodeIfNeeded) {
throw new Error('useSpatialNavigatorParentScroll must be used within SpatialNavigatorParentScrollContext.Provider');
}
return { scrollToNodeIfNeeded };
};
(4) I rebuilt the package with my changes above, and replaced the /dist in my nodes_modules with my new changes. I immediately got the error that the context was being used outside the provider. (Which React 19 is more strict than before)
(4.1) I also ran these changes directly in the packages/example:
(5) I can fix the error if I remove references to useSpatialNavigatorParentScroll() in the following two components:
A - Node.tsx (packages/lib/src/spatial-navigation/components/Node.tsx)
B - ScrollView.tsx (packages/lib/src/spatial-navigation/components/ScrollView.tsx)
TLDR:
This seems to confirm that the root cause is that useSpatialNavigatorParentScroll() is being used outside of the SpatialNavigatorParentScrollContext.Provider (which I believe React 19 is more strict about than prior versions)
I suspect these are the ones I am running into - but it would be prudent to apply safer checking throughout all components
I know @lKinderBueno provided you with his reproducible code - For reference, I am using AmazonAppDev's tv template which I've been updating to use expo 53, react 19 and react-native 0.79. This is my last package to update, once fixed, I will PR their react-native-multi-tv-app-sample with the upgrades!
Hey @iAMkVIN-S ! Thank you so much for the deep dive. That's super helpful. I will have a look as well! It's a bit weird to have an issue because of the context consumer is used outside the provider. It's supposed to use the default value in this case (which is a convenient and expected feature of the context) π€ Also, I haven't heard of this breaking change.
I will have a look.
Thank you all for your help, I'm sure we'll be able to release this soon!
So I just had a look! I really can't manage to reproduce.
I tried:
- to set up your repository @lKinderBueno, but I can't build the app. watch man just times out no matter, I don't understand why. So I can't try it π€
- I tried to extract the example app, replaced the imports as you did, and tried to install
[email protected]... and it worked well π€ - I also tried to have Node components outside a ScrollView context... It worked well without any crash π€
About the context hypothesis: I really think that having a consumer outside a provider is not a problem. It would be a huge breaking change and it really is a feature (it's the only point of the context's default value, actually).
@iAMkVIN-S if you have another reproducible example to share I would be super grateful. I can't investigate this since I can't reproduce at all π
Edit: I just saw that you did give an example. I will have another look tomorrow! Thank you!
Bon matin @pierpo π,
Thank you so much for investigating π I must be wrong on the underlaying cause of the error... but can assure you the error itself does exist!
I'm currently on mobile, but let me try to get you some steps to get the error on your side:
(1) Clone the AmazonAppDev React Native Multi-Tv App Sample
git clone https://github.com/amazonappdev/react-native-multi-tv-app-sample.git
(2) Replace the package.json with these up-to-date package versions
{
"name": "test",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "EXPO_TV=1 expo start",
"android": "EXPO_TV=1 expo run:android",
"ios": "EXPO_TV=1 expo run:ios",
"web": "expo start --web",
"test": "jest --watchAll",
"lint": "expo lint",
"prebuild": "EXPO_TV=1 expo prebuild --clean",
"prepare": "husky",
"format": "prettier --write ."
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@bam.tech/react-native-keyevent-expo-config-plugin": "^1.0.50",
"@expo/vector-icons": "^14.1.0",
"@react-navigation/drawer": "^7.1.1",
"@react-navigation/native": "^7.0.14",
"@typescript-eslint/eslint-plugin": "^8.12.2",
"@typescript-eslint/parser": "^8.12.2",
"expo": "^53.0.20",
"expo-build-properties": "~0.14.8",
"expo-constants": "~17.1.7",
"expo-dev-client": "~5.2.4",
"expo-font": "~13.3.2",
"expo-linear-gradient": "~14.1.5",
"expo-linking": "~7.1.7",
"expo-router": "~5.1.4",
"expo-splash-screen": "~0.30.10",
"expo-status-bar": "~2.2.3",
"expo-system-ui": "~5.0.10",
"expo-web-browser": "~14.2.0",
"lint-staged": "^16.1.2",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "npm:react-native-tvos@~0.79.5-0",
"react-native-gesture-handler": "~2.24.0",
"react-native-keyevent": "^0.3.2",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-video": "^6.8.0",
"react-native-web": "~0.21.0",
"react-tv-space-navigation": "^v6.0.0-beta1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@react-native-tvos/config-tv": "^0.1.3",
"@types/jest": "^29.5.12",
"@types/react": "^19.1.9",
"@types/react-test-renderer": "^19.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"eslint": "^9.13.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-native": "^5.0.0",
"husky": "^9.1.6",
"jest": "^30.0.5",
"jest-expo": "~53.0.9",
"prettier": "^3.6.2",
"react-native-pixel-perfect": "^1.0.2",
"react-test-renderer": "19.1.1",
"typescript": "~5.3.3"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"prettier --write"
],
"*.tsx": [
"prettier --write"
]
},
"expo": {
"install": {
"exclude": [
"react-native"
]
}
},
"private": true
}
(3) Install the dependencies
npm install --legacy-peer-deps
(4) Run the web project
npx expo start --web
You should get the error right away.
For reference, you will not get the error if you skip step 2 (use old package versions) or if you update the packages but comment out lines 167-174 of app/(drawer)/index.ts
<SpatialNavigationScrollView
offsetFromStart={scaledPixels(60)}
style={styles.scrollContent}
>
{renderScrollableRow("Trending Movies", trendingRef)}
{renderScrollableRow("Classics", classicsRef)}
{renderScrollableRow("Hip and Modern", hipAndModernRef)}
</SpatialNavigationScrollView>
Hope this helps and sorry if instructions are missing, I wrote this from the car on my phone π₯²
EDIT:
After updating the packages, if memory serves me well you get an error that is fixed by removing all the imports of React (import React from "react" sometimes the import is joined with other things like useEffect or useState)
In components/player/VideoPlayer.tsx add import { forwardRef } from "react"; and replace
const VideoPlayer = React.forwardRef<VideoRef, VideoPlayerProps>(
with
const VideoPlayer = forwardRef<VideoRef, VideoPlayerProps>(
Thank you so much @iAMkVIN-S! It turns out I had issues on this repo as well, because my watchman was outdated. Sorry that I didn't spot it yesterday on the other example.
I got to reproduce super quickly and easily. Thank you both.
Good news: I made some progress. It does come from the ScrollView. And more precisely, from the CustomScrollView, which is a ScrollView that we implemented with a CSS scroll for a smoother behaviour.
If you use useNativeScroll on the scroll views, I think the beta will probably work.
In the meantime, I will investigate what precisely in the CustomScrollView causes the crash π€
Wow. I have cut down the problem to this:
On lib's end
// ScrollView.tsx
import { View } from 'react-native';
export const SpatialNavigationScrollView = () => {
return (
<View>
<View />
</View>
);
};
SpatialNavigationScrollView.displayName = 'SpatialNavigationScrollView';
On example's end
import { useIsFocused } from '@react-navigation/native';
import { useMenuContext } from '../../components/MenuContext';
import { SpatialNavigationRoot, SpatialNavigationScrollView } from 'react-tv-space-navigation';
export default function IndexScreen() {
const { isOpen: isMenuOpen } = useMenuContext();
const isFocused = useIsFocused();
const isActive = isFocused && !isMenuOpen;
return (
<SpatialNavigationRoot isActive={isActive}>
<SpatialNavigationScrollView />
</SpatialNavigationRoot>
);
}
**This reproduces the problem π **
However, removing one nested view from the scroll view removes the issue. I don't understand.
// ScrollView.tsx
import { View } from 'react-native';
export const SpatialNavigationScrollView = () => {
// β
This works. WTF π£π€―
return (
<View />
);
};
SpatialNavigationScrollView.displayName = 'SpatialNavigationScrollView';
I'll keep investigating tomorrow!
I kept looking a bit, and I found that this has probably been solved in React 19.1.0
https://github.com/facebook/react/pull/32117
It looks like the problem happens with 3rd party libraries (like this one) when they are served bundled only for production mode π€ I got mixed up a bit and I can't reproduce anymore, but if any one of you could check that React 19.1.0 does work I would appreciate π€ I'll keep investigating and try to find a proper fix!
I kept looking a bit, and I found that this has probably been solved in React 19.1.0
It looks like the problem happens with 3rd party libraries (like this one) when they are served bundled only for production mode π€ I got mixed up a bit and I can't reproduce anymore, but if any one of you could check that React 19.1.0 does work I would appreciate π€ I'll keep investigating and try to find a proper fix!
I ran some checks with React 19.1:
- Web: works fine.
- Android: breaks due to a version mismatch. React 19.1 needs [email protected], which comes with RN 0.80.
- RN 0.78 and Expo 53 only supports React 19.0.
- React 19.1 is supported starting with RN 0.80, supported starting from Expo version 54. but 54 is still canary, not production-ready.
I tried Expo 54 and everything worked on both Android and web. Given the canary status, my suggestion is to stick with Expo 51 for now and wait Expo 54 to be officially released.
This is the package.json I used:
{
"name": "hoppixtv",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "EXPO_NO_CLIENT_ENV_VARS=1 EXPO_TV=1 expo run:ios",
"web": "expo start --web",
"build:web": "expo export -p web",
"test:types": "tsc",
"prebuild": "expo prebuild --clean"
},
"dependencies": {
"@bam.tech/react-native-keyevent-expo-config-plugin": "^1.0.52",
"@emotion/native": "^11.11.0",
"@emotion/react": "^11.11.3",
"@react-native-tvos/config-tv": "^0.0.4",
"@react-navigation/bottom-tabs": "^6.5.11",
"@expo/metro-runtime": "~5.0.4",
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.17",
"@types/jest": "^29.5.12",
"@types/react-test-renderer": "^19.1.0",
"babel-jest": "^29.7.0",
"expo": "54.0.0-canary-20250729-d8899ae",
"lodash": "^4.17.10",
"expo-status-bar": "~2.2.3",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-watch-typeahead": "^2.2.2",
"lucide-react-native": "^0.335.0",
"react": "19.1.0",
"react-native": "npm:[email protected]",
"react-dom": "19.1.0",
"react-native-keyevent": "^0.3.2",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-svg": "15.12.1",
"react-native-web": "~0.21.0",
"react-tv-space-navigation": "^6.0.0-beta1",
"typescript": "~5.8.3"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"babel-plugin-module-resolver": "^5.0.0"
},
"private": true,
"expo": {
"install": {
"exclude": [
"react-native"
]
}
}
}