-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding support for LazyColumn (FlatList) #9
Comments
@fabOnReact Hello! I am no expert, but Column doesn't scroll by default. I think you need LazyColumn for that to scroll. I tried implementing it but it was giving me errors so I stopped for now. If you can get it working that would be great! As for limitations of compose in RN, it's just very untested. There are some kinks we need to work out and it doesn't always work how you'd expect. I'm hoping to solve most of the issues in this library though. |
fabOnReact/react-native-wear-connectivity#12 (comment) my problem with ScalingLazyColumn was rendering a ViewGroup, like done with FlatList renderItem and data. I believe there is a difference in implementation between LazyColumn and FlatList. LazyColumn maybe is a similar implementation to RecyclerView. The problem is that with our React Native architecture handles in JavaScript the virtualization (mounting and unmounting of items in a list), which may not be compatible with this APIs.
There is an implement of RecyclerView (react-native-recyclerview-list), but the library has some limitations.
I don't believe there is an easy way to do this. Many big companies like Shopify, Flipkart did not try to use RecyclerView, instead they followed the FlatList implementation which leverages ScrollView native API. You may be able to render the Jetpack Compose items (like Text) in a traditional ScrollView. |
there is a way to implement this, building a new API based on WearableRecyclerView or RecyclerView or LazyColumn: Using JSI may mean skipping renderer, that is why there is no support for setState or update props for components rendered in the renderItem function registered on native side with createFromHostFunction https://github.com/facebook/react/tree/main/packages/react-reconciler also I don't think createFromHostFunction supports JSX, because the renderer is responsible for creating native views like TextView from JSX views like Text probably is similar implementation to the one used in https://github.com/godness84/react-native-recyclerview-list/blob/864021c01ef42b1a451c526c8f65a30ff33c2d2a/android/src/main/java/com/github/godness84/RNRecyclerViewList/RecyclerViewBackedScrollView.java#L191-L200 react-native-recycler-view uses ViewGroup addView |
You’ve outlined a theoretically possible approach—essentially bypassing React Native’s usual rendering and reconciliation pipeline by registering a native-side renderItem function using the JSI (via something like Function::createFromHostFunction). This would let you feed data and trigger UI updates directly from native code, potentially driving a Compose list component without going through the normal React Native “VirtualizedList → ScrollView → native views” pipeline. However, this approach comes with significant challenges and limitations:
React Native’s architecture relies on the React renderer (reconciler) to interpret JSX and update the native UI tree accordingly. Without it, you are stepping out of the standard React Native lifecycle:
You mentioned implementing a custom API to handle setState and updating props. In normal React Native, setState on the JS side triggers a reconciliation pass that updates native views. By sidestepping this and implementing your own “state management,” you assume responsibility for:
Function::createFromHostFunction allows you to create a JSI function that JS can call, but integrating this neatly into a React Native app is non-trivial:
The react-native-recyclerview-list library attempted a similar low-level integration by using RecyclerView. The issues encountered there—like having to manually trigger updates because setState wouldn’t automatically re-render items—illustrate the kind of complexities you’ll face. React Native’s architecture is optimized around the idea that the JavaScript side controls the layout and updates declaratively, while the native layer provides a stable set of host components (like ScrollView, Text, View). Once you step outside that contract and try to integrate a radically different approach (Compose’s LazyColumn or ScalingLazyColumn) via JSI host functions, you no longer benefit from that architecture.
As React Native evolves (particularly with the Fabric renderer and TurboModules), you may find that maintaining a hand-rolled integration becomes even more difficult. Future changes in the way React Native’s reconciler or JSI integration work may break your carefully crafted solution. Without a stable API designed for this use case, you’ll be doing a lot of maintenance. In conclusion, while your outlined approach is theoretically possible, it’s akin to building a custom, partial React Native renderer on the native side for Compose-based lists. You’d be forgoing the standard reconciler, losing JSX and declarative updates, and taking on manual state and update management. This is a high-complexity, low-leverage solution. Unless you have a very specific reason and the resources to maintain this custom integration layer, it’s generally easier and more sustainable to stick within the supported paradigms—using ScrollView and FlatList, or creating a very specialized native module that at least mimics how the reconciler and Fabric renderer handle updates. |
Hey! This is a lot of research thanks. I'm not sure I'm following the issue tho. What exactly is the problem you're trying to solve? The goal of this library is to simply expose compose views to RN @fabOnReact |
I understand now your point. LazyColumn for you is not an essential component because you can use FlatList or ScrollView with Jetpack Compose views (issue fabOnReact/react-native-wear-connectivity#12). react-native-wear-connectivity allows to develop android WearOS apps using react-native (for example develop for WearOS with react-native components like, ScrollView, Text etc..). Most of the WearOS APIs are written in Compose, so I need to make those APIs available to React Native Developers. The most important ones are ScalingLazyColumn (which is based on LazyColumn) or WearableRecyclerView to support circular scrolling. As explained in the above comments, I think it's hard to implement LazyColumn in React Native. BUT I think I can quickly re-implement WearableRecyclerView following the same approach from react-native-recycler-view (which uses ViewGroup addView to add the items from FlatList renderItem to the RecyclerView). I believe this is the same approach you are using in this library (you add a compose component to an Android ViewGroup using addView). I can use the same approach with WearableRecyclerView, so that we can support circular scrolling on React Native for WearOS. Once I have that done, users can build WearOS apps using your Jetpack Components or the WearOS JetPack Compose components. I opened this issue to collaborate and share toughts on how to implement LazyColumn in React Native. |
@andrew-levy it is not clear from the readme that you do not plan to support LazyColumn. Could you give me some feedback on that because I don't understand if you are interested in working on LazyColumn together or instead you don't plan to build a component around the JetPack Compose LazyColumn implementation. |
Related Issue fabOnReact/react-native-wear-connectivity#12
What are the limitations of using
LazyColumn
component instead of traditionalScollView
?What are the limitations of using Jetpack Compose Components with React Native?
Searching ShikaSD in react-native-community/discussions-and-proposals#446 brings up some interesting info.
I would like to add support for ScalingLaxyColumn in the library as it is important for WearOS development with
react-native-wear-connectivity
.cc @gaurav21r also interested in helping with this
I'm asking you, as you probably investigated limitations and maybe found workarounds around them. Thanks a lot
The text was updated successfully, but these errors were encountered: