Open mrjackdavis opened 1 year ago
Same issue for me. Took me a while to figure out what was wrong - i have a nested context provider overriding the parent one, but everything inside
From my understanding, that's currently not feasible in React Native. I've stumbled upon It's fine lib recently (https://github.com/pmndrs/its-fine) that has a useContextBridge hook. It looks like the library supports React Native, it might be interesting to experiment with it.
After a lot of digging, I found out that Modal
is designed to be the replacement for React Native Portal
which was deprecated long ago.
At first glance, I found this preposterous. But after some reflection, I think it makes sense. Portal
, almost by design, is a DOM thing. And Modals
aren't a first-class citizen in the DOM.
The opposite is true for RN. Modals are first class, Portals are a hack.
So I practically rewrote a couple of libraries I used that depend on react-native-portal
to just use Modal
. It works so much better.
I think this library can be misleading and is applied in situations where Modal
is more appropriate. e.g. react-native-bottom-sheet/modal
and react-native-hold-menu
@gorhom - you're the author of both react-native-bottom-sheet
and this library. Have I missed something here? Why exactly have you used react-native-portal
over Modal
in react-native-bottom-sheet
?
portals have no "cost", they are a virtual thing. Modal is a tangible component that adds another layer to your UI and can cause some inconsistent/unexpected behaviour as it is dependant on both React Native's implementation and platform's own implementation which can change between OS versions
Portals aren't a DOM thing, they're a hierarchy thing. The purpose of a portal is to enable declarative rendering from within a given component to a target that is higher up in the tree. If you just use Modal
you'll likely end up using context and calling some sort of global-ish showModal()
function to trigger it, and at best passing in a rendering function to make things somewhat declarative. It works, but it's implicit. I expect to define my modal in the relevant context and have a mechanism to render it elsewhere as an implementation detail.
Hey!
I come from
ReactDOM
land whereReactDOM.createPortal
exists and I see this library as the react-native alternative.One key behaviour of
ReactDOM.createPortal
that I've come to expect, is that a rendered component that is portaled, maintains the context of where the element was defined.See this issue for an example https://github.com/enesozturk/react-native-hold-menu/issues/82#issue-1403702172
I can also see confusion about this behaviour in #2, #3 and #31. The workaround seems to be to either re-order context providers. I have some cases where that is not feasible.
I dove into the source and understand why the behaviour is as it is.
@gorhom, have you thought about this previously? Is there a way to arrive at this behaviour without some sort of first-class implementation by react or react-native?