React Native visionOS allows users to create multi-window applications, this feature allows you to build feature-rich apps that use full capabilities of the framework. In this blog post we will go over how you can build multi-window counter application with global state.
Setup
In order to get started, let's create a new visionOS application using this command:
Next, go inside the generated project and install pods inside of visionOS folder:
After installing pods, you can run following command to build the app to the simulator:
Adding second window
Note: Adding new windows is described in detail in the documentation.
This process involves three steps:
Enable Multiple Window support
Add native entry point
Declare new JS component
Enable multiple window support in Info.plist by changing UIApplicationSupportsMultipleScenes to true:
Add additional RCTWindow in visionos/App.swift with reactContext, which allows us to share pass data between JS and native. Make sure that the id is unique for each window and matches the one in the JS code.
Declare new JS component in index.js
Let's create a component that's going to be used as our window:
And add it to index.js file:
Next, let's add some code to open and close the window:
Pressing on buttons should open new window. We are all set! Now, let's discuss state managers.
Choosing state manager
In most cases choosing state manager lies in personal preferences, performance, API design and more. However when it comes to sharing data across multiple windows the options are limited. As you saw from the setup above we have separate React roots, one for each window. Which makes using state managers that require wrapping our app in a provider not a viable option.
React Native is sharing the same javascript context across windows. Which makes it possible to either pass some custom store to the App and Counter or use a state manager like Zustand that does it for you without need to wrap the apps with a Provider.
Let's install Zustand and create a simple store to share data.
Create a file called store.ts and implement a simple store:
Next, let's use the store in both of our windows (main one) and the Counter window:
And inside of Counter.tsx:
Now we have seamless data sharing across two windows! Demo:
That's all
And that's it! I hope you found this article useful. If you have any questions or feedback feel free to reach out to me on Twitter.
For those interested in the sample code, you can find it in the GitHub Repository.