Why 95% of Modals should be Local (in React)

Global vs Local Modals - it is a great architectural question that you should answer when coding your app.
⏱️Timestamps:
00:00 - z-index stacking issue
00:19 - React Portals
00:27 - Global Modal Architecture Trend
01:08 - Modal's Law
01:22 - Problems with Local Modals
02:10 - Global Modal comparison
02:33 - "Dumb" Implementation
03:09 - "Sophisticated" Implementation
05:05 - Global vs Local Modal
05:18 - Costs of Global Modal Architecture
05:52 - Rendering Problem
06:10 - Context Problem
06:53 - Why Local Modals drawbacks are rly not that bad
08:45 - When Global Modals are actually useful
09:28 - The Rule of Least Power
📖 Further Reading and Acknowledgments:
- Nice Modal React - Announcement: / rethink-modals-managem...
- Nice Modal React - GitHub: github.com/eBay/nice-modal-react
- Elon Musk interview from Everyday Astrounat: • Starbase Tour with Elo...

Пікірлер: 67

  • @jshstuff
    @jshstuff13 күн бұрын

    I wasn’t aware people were commonly considering having such engineered modal solutions with registries and such. local modal instances with a teleport have always seemed very elegant to me. as others have mentioned, the only tricky thing is handling multiple modal instances open at the same time. I really like this kind of video!

  • @MaxGJPanas
    @MaxGJPanas14 күн бұрын

    Great stuff. One thing you didn't touch on which comes up every now and then is how each solution handles modal-ception i.e. modals launching further modals on top of previous modals. e.g. a modal for accepting payment configuration which triggers another modal to confirm you really want to close it and exit the payment flow (bad example maybe, but you get the idea).

  • @ziriusph3395

    @ziriusph3395

    13 күн бұрын

    yes, I'm surprised it wasn't tackled at all. Do UI developers dodged building apps without having to implement multimodal?

  • @asadsalehumar1011

    @asadsalehumar1011

    13 күн бұрын

    Personally I tried to avoid nested modals. I think its bad for both developers and users. Bad DX & bad UX => should avoid. Maybe the solution is to change the first modal into a side panel and keep the second modal as a modal.

  • @ziriusph3395

    @ziriusph3395

    13 күн бұрын

    ​@@asadsalehumar1011 you have no choice if the UI/UX designer said it's how it should be built and it's the most scientific UI behaviour. Plus, mobile games are full of them, which means they are generally expected by the userland.

  • @InfinityFnatic
    @InfinityFnatic13 күн бұрын

    Global modal store that handles stacking multiple modals, and each modal is impored locally where needed and shown imperatively using the store, that is the best approach after a lot of trial and error.

  • @1v512
    @1v51214 күн бұрын

    good introduction, with great understanding of modal's law, then deep into thinking React and ending with design principles. Outstanding content.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    ty ❤

  • @xorlop
    @xorlop14 күн бұрын

    I think this is reasonable given that we now have the popover api. The actual rendering, not react, but html rendering, made creating modals themselves a real challenge. Maybe I am misremembering, but I think that was the main reason people chose to use portals for modals.

  • @rand0mtv660

    @rand0mtv660

    14 күн бұрын

    Portals are used so that you can avoid weird z-index issues because something later in DOM would overlap your modal. Rendering modal inside the document body, but still inside your JSX tree locally is great for composition and avoiding these issues. Same things were done with modals before React. You would usually place modal HTML before closing body tag so that modals render last in HTML.

  • @prikshit8
    @prikshit814 күн бұрын

    Underrated channel

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    ty ty ❤

  • @haritssyah7434
    @haritssyah743414 күн бұрын

    I like this type of video! Keep going!

  • @LeprekusGaming
    @LeprekusGaming13 күн бұрын

    Hey! This is a really nice video very informative. What software do you use to edit and add assets like the arrow in 4:03

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Thanks! ❤ I animate 95% with basic options in DaVinci Resolve. And this arrow is just 5 different arrows combined in some online gif converter 😅

  • @minyoungna6642
    @minyoungna664214 күн бұрын

    I agree with Kent's approach hard - just encapsulate the modalic nature ( opening / closing ) inside the component. My only use case for global modal is nested structure where one modality may interfere with some modal in a different tree ( imagine a shopping cart that has a notification pop up, but shopping cart is only rendered )

  • @samyipsh5381
    @samyipsh538114 күн бұрын

    that was a great explanation, thx!

  • @dulranga_2
    @dulranga_214 күн бұрын

    this is great content !!

  • @Brian-bo2fu
    @Brian-bo2fu14 күн бұрын

    I do agree your point on local modals can reduce rerender but how can you make sure that global modals and local modals are showed in sequence. With global modal management, you can implement queue to make sure your global modal never interrupts local modals. This is usually happen when you have to do some data polling for example: Polling every 30 mins to check if a new version released and show a version update reminder if there is new version

  • @yektadev
    @yektadev12 күн бұрын

    This is an interesting perspective. I don't use React, but I implemented a global modal architecture for a Compose-based app. Yes, it has all the mentioned downsides. However, in case of the global modals, you can look at your modal layer as a "Screen in another dimension". It can have it's own navigation logic just like the "main" screen and with that you can implement almost any imaginable use-case. Local is definitely easier to read and faster to grasp, but isn't suitable for complex use-cases. The classic "it depends".

  • @user-zz7ko2vj2f
    @user-zz7ko2vj2f12 күн бұрын

    The "big" problem of re-rendering the entire application due to calling a global component is solved by simply creating a separate instance of the React application for this. This worked effectively in different scenarios for me, in particular for Vue and for React

  • @MarlonEnglemam
    @MarlonEnglemam3 күн бұрын

    local modals have always made sense to me! The only thing I dont like about them in react is the syntax that usually will be like: { isOpen && } for some reason I find it not elegant but at the end of the day it works fine so I stick with it!

  • @antonmaslyukov689
    @antonmaslyukov68914 күн бұрын

    Good video, but there is one step further, no open state, easier to chain, easier to handle returned value from modal, no element mounted until called, configurable from local component, no registration. It all comes to promise and createRoot, no portal needed, describe jsx once and then configure each modal as need locally. Make a global function for opening modal, that takes component and props as second argument, then get body, create and attach div, make this div as root and return promise, modal will get two props proceed - function to resolve promise with values, and close - function to reject promis with some kind of info/error. On close you just unmount root and remove created element and you done. As some of the modal can be reused, simply wrap open function, described previously, and make new function accept only props for modal, and there you have it, openConfirm, openInfo and many other. I have been working with this solution for quite a while, didn't notice any hiccup, the core took 28 lines with empty lines to space things up

  • @user-ik7rp8qz5g
    @user-ik7rp8qz5g12 күн бұрын

    What about html dialog element? Does it help making modals in any way?

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Yes! Whether you choose local or global, in both cases you would probably want to build some generic ModalWrapper, this is where you will want your Dialog element.

  • @vazus171
    @vazus17112 күн бұрын

    Personally I prefer modals to be global so that I simply open then from events, without need to define state and add component. Semantically it's not the best idea, but it's the easiest to use for me. Like that: const dialog = useDialog(); Then in component's JSX: onClick={() => dialog.open()} useDialog() is a context wrapper that gives us open and close methods. Open method takes a component as a prop.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    That's interesting take, but I think your preference comes from the power of habit. I mean, maybe you just feel more comfortable with imperative paradigm? React is declarative and imho it's better to fully embrace it's nature, or u will find yourself swimming against the tide too often. But that's just my opinion.

  • @maixior123
    @maixior1235 күн бұрын

    where are you from? Your accent sounds kida polish?

  • @Eghizio
    @Eghizio13 күн бұрын

    Good stuff. That's how I've been doing modals so I can now pat myself on the back :D

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Haha, love it XD

  • @neociber24
    @neociber2412 күн бұрын

    I'm a little lost here, the children won't rerender if the ModalContext don't have children, take for example the react-hot-toast library, their provider don't have children, just store the state of the toasts to render. You can do the same with modals.

  • @anon5992
    @anon599212 күн бұрын

    imagine quoting from someone who ordered other software developers to print their code in a coding video. nice vide btw local modals way to go

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Good call out, maybe I shouldn't. But I think this quote is gold.

  • @rand0mtv660
    @rand0mtv66014 күн бұрын

    5:54 And btw, as far as I know using Context doesn't re-render everything, it just re-renders child components that actually consume context using useContext hook. So if you have a tree like "Context > A > B > C" and component C is the only one consuming that Context, it will be the only child component in that tree that will re-render on that Context change. A and B will not re-render because of Context value change.

  • @Mankepanke

    @Mankepanke

    14 күн бұрын

    No, all children of the provider will rerender. A > FooProvider > B > C > use Foo. If foo changes, then the provider will rerender, which requires all nested render functions to run.

  • @rand0mtv660

    @rand0mtv660

    14 күн бұрын

    @@Mankepanke yeah sorry, I think you are right. I believe I've read somewhere long time ago that it will skip re-rendering immediate "children" so that means only components that use useContext will actually re-render. Might only be true in cases where immediate children are wrapped in React.memo(). Then React will see children have same props and won't re-render immediate "children", but only Context consumers.

  • @joelv4495

    @joelv4495

    14 күн бұрын

    @@Mankepankeyep. Some state libs like zustand have the affordance to subscribe to a subset of the global store.

  • @athulgeorge6744

    @athulgeorge6744

    13 күн бұрын

    @@Mankepanke Yes this is how it works, but I wonder if this will change with react forget.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    ​@@athulgeorge6744 good point! I guess React Compiler will change the game.

  • @diegoignacioalvarezespinoz3965
    @diegoignacioalvarezespinoz396514 күн бұрын

    Why dont you use Zustand and use global modals?

  • @nhieljeff2156

    @nhieljeff2156

    14 күн бұрын

    exactly

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    You can, but that only solves prop-drilling and re-rendering and I've listed more arguments for local modals. I also said in the vid: use context OR some global state mgmt library. So go for Zustand if u rly need global modals, I only say that local modals often suffice :)

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Zustand is even better than context imho

  • @naranyala_dev
    @naranyala_dev13 күн бұрын

    I just chose one of the reusable options, easy to put into another projects with less keystroke

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    If u need global modal, sure 👍

  • @MichaelSoriano
    @MichaelSoriano13 күн бұрын

    Wish I would've seen this earlier. I went the global route - and regretting it. Too complicated.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    We learn the most on our mistakes 😁 Glad you have found my vid then, simplicity often (but not always) wins 😊

  • @bartlomiejuminski
    @bartlomiejuminski14 күн бұрын

    I don't like react but this video is high quality

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    ty much! ❤

  • @maximroslow
    @maximroslow13 күн бұрын

    i was fired because of local modals don't do it

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    are u serious? 😅

  • @nhieljeff2156
    @nhieljeff215614 күн бұрын

    yeah but zustand fixes this

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    It only fixes prop-drilling and re-rendering. But I agree that could be a good choice if you rly need global modal, probably better than using context

  • @mpowereer6992
    @mpowereer699213 күн бұрын

    POLSKA GUROM!!!

  • @mahmoudzakria6946
    @mahmoudzakria694613 күн бұрын

    Use HTML5 Dialog element.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    Yup, that can be used for the ModalWrapper component, I tried not to mix too many topics at once

  • @justgame5508
    @justgame550813 күн бұрын

    W take from Elon

  • @netssrmrz
    @netssrmrz14 күн бұрын

    good video, though it's a shame to see UIE talents wasted on react. regarding the topic; this is only an issue, in react, because of the ridiculous vdom and hierarchical component scope structure, in my opinion. in the end, when forced to work with react, i agree with the approach demonstrated.

  • @rand0mtv660

    @rand0mtv660

    14 күн бұрын

    This is not a React only issue. For example Vue has a Teleport component that is equivalent to React's Portal to render HTML outside of the component tree. So there if you want to use a local modal, you will have to render it locally the same in code and if you want it globally you will most likely have to do something similar, just different code because it's Vue.

  • @netssrmrz

    @netssrmrz

    14 күн бұрын

    @@rand0mtv660 ok so Vue has the same issue, again for the same reason. In the DOM There is no inherent limit on accessing components outside of the local component tree (Web Component API). These are artificial issues created by frameworks.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    @netssrmrz thanks! Yup, I agree that's just the cost of using a framework. We can all go back to pre-framework era but I don't think it's good solution either. Everything has a cost.

  • @UIEngineering

    @UIEngineering

    7 күн бұрын

    And sorry to disappoint but I'm planning to cover a lot of React-related stuff for now. But I will definitely try to cover more general topics in web dev as well.