Skip to content

Conversation

@myers
Copy link
Contributor

@myers myers commented Oct 8, 2025

My problem

I had a React Dom component that I wanted to show buttons to enter VR/AR, or show not supported when not supported. These work great in development when they've been added via HMR, but on fresh reload, when IWER hasn't loaded, they would switch to "XR not supported" because that's what useXRSessionModeSupported told them and stay that way because there wasn't anyway for them to know IWER finishes setting up. I can go with polling solution in this case, but I felt we could make it better with events.

In IWER I added meta-quest/immersive-web-emulation-runtime#119 which will make use of the devicechange event. I'm hoping they will accept this change, but even if not, handling the devicechange event and updating the hooks seems like the right idea.

There is an extra twist, IWER replaces the navigator.xr object, so we have to unsubscribe from the previous object and subscribe to the new one.

Solution

Replaces the implementation that kept state in a useMemo closure with a singleton external store that lives outside React's lifecycle. This ensures useSyncExternalStore works correctly across component mounts. With the addition of event this is a lot more like the navigator.online example they give in the react docs.

Applications need to detect when XR devices become available and update their UI accordingly. The hook now listens to devicechange events and maintains backward compatibility with the optional onError parameter.

I would be happy to add a test if that would be helpful.

Replaces the implementation that kept state in a useMemo closure with
a singleton external store that lives outside React's lifecycle. This
ensures useSyncExternalStore works correctly across component mounts.

Why?
Applications need to detect when XR devices become available and update
their UI accordingly. The hook now listens to devicechange events and
maintains backward compatibility with the optional onError parameter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant