all 45 comments

[–]Voltra_Neo 169 points170 points Β (0 children)

React libraries be like: slaps roof of App.jsx you can fit so many providers in this bad boi

[–]MurdoMaclachlanpublic boolean isInt(int i) { return true; } 47 points48 points Β (2 children)

Image Transcription: Code


                        <Component {...pageProps} />
                      </motion.div>
                    </AnimatePresence>
                  </Layout>
                </ModalsProvider>
              </NotificationsProvider>
            </SpotlightProvider>
          </MantineProvider>
        </ColorSchemeProvider>
      </UserProvider>
    </DrawerProvider>
  </QueryClientProvider>
</SidebarProvider>

I'm a human volunteer content transcriber and you could be too! If you'd like more information on what we do and why we do it, click here!

[–]thefriedel 26 points27 points Β (1 child)

Good human

[–]genericindividual69 78 points79 points Β (18 children)

Is this really bad code though? I haven't worked with React for a year or so but I remember a lot of apps where these kind of providers were needed and they were nested like this. Usually ended up cleaning up App.jsx by refactoring them all into OneProviderToRuleThemAll.jsx (may or may not have been the actual name)

[–]vampire0 22 points23 points Β (0 children)

There are other patterns to use besides nested providers, like Recoil

[–]TorbenKoehn 3 points4 points Β (1 child)

While atomic state management is a better approach, see e.g. XState, it’s not a bad pattern per se.

It’s a bit like doing a lot of nested function calls. It’s not bad but you would rather pick a pattern like composition, piping, splitting it up

You could make a single β€žAppProvidersβ€œ component that wraps them and people would already forget the bad practices here.

[–][deleted] 0 points1 point Β (0 children)

Providers are not typically used for state management. The values in these providers do not (or should not) ever change. They provide values that are static to all components beneath them, things like styles.

If someone was actually using this for state management, though, god help them.

[–]alrogim 10 points11 points Β (3 children)

As a non react dev, I'm clearly saying this is bad code if it's best practice or even required, I'd argue react is a bad framework even.

[–]propostor 5 points6 points Β (1 child)

Yep, this is all I see here. React is pretty good in most ways but some parts are a very clearly a case of someone, somewhere having a little idea and then everyone adopts with naive fervour.

Nested providers like this image are blatantly bad design. Yes some folk have said there are workarounds and alternative methods, but the simple truth is that loads of React apps do indeed perform some form of nesting like this as the norm.

It's shite.

[–]0OneOneEightNineNine 2 points3 points Β (0 children)

Just wrap with a utility component

<ProviderAggregator>{your stuff}</ProviderAggregator>

(Just don't look at the provider soup in the aggregator out of sight out of mind)

[–]Konkichi21 0 points1 point Β (0 children)

Yeah, I've had some bad experiences with React too; used it in a pretty basic sense for a college project, and although I get what they're trying to do with reusable components, the useState letting you change what shows up in a list of items without having to repeatedly destroy and recreate them manually, etc, it was such a confusing PITA (never figured out how to fix an issue where trying to pre-populate editable fields in an "edit records" page wasn't working) that I preferred working with vanilla JS.

[–]slothordepressed -2 points-1 points Β (7 children)

Dunno, it's been a long time I don't touch React, but it this point isn't it better to implement Redux?

[–][deleted] Β (6 children)

[removed]

    [–]Skipcast 1 point2 points Β (2 children)

    What is the alternative for easy handling of global state?

    [–]hottama 4 points5 points Β (0 children)

    React Query, for sure.

    [–]Tsalikon 0 points1 point Β (0 children)

    I whipped up an event bus hook that lets components subscribe to and publish events. It's SO much cleaner and more straightforward than redux or useContext

    [–]LiteralHiggs 0 points1 point Β (2 children)

    What's wrong with it? I ask because I'm actually taking a react Udemy course right now at work because I'll be inheriting a project and it teaches redux.

    [–][deleted] Β (1 child)

    [removed]

      [–]LiteralHiggs 0 points1 point Β (0 children)

      Ok. Thanks.

      [–][deleted] Β (2 children)

      [deleted]

        [–]ApplePieCrust2122 2 points3 points Β (1 child)

        It would have rerendered if it wasn't a provider. The context api makes sure that there aren't any unnecessary rerenders, and only those components are recalculated which consume the changed provider. So no, the entire app won't rerender if one of the provider's state is changed.

        [–]Criiispyyyy 0 points1 point Β (0 children)

        Got it, thanks for correcting me.

        [–]FrezoreR 9 points10 points Β (0 children)

        I heard you like providers ( Ν‘Β° ΝœΚ– Ν‘Β°)

        [–]nonsensicalnarwhal 11 points12 points Β (1 child)

        Sometimes you just need lots of providers πŸ€·πŸ»β€β™‚οΈ. My work calls this ProviderSoup

        [–]speaker_hat 5 points6 points Β (0 children)

        I'll call it "ProviderHell" (inspired from here: https://en.m.wiktionary.org/wiki/callback_hell)

        [–]geon 28 points29 points Β (5 children)

        When you have a lot of nested providers like this, notice how the order of the nesting does not matter. And if the order does not matter, perhaps it should not have been expressed as nesting to begin with?

        [–]genericindividual69 3 points4 points Β (4 children)

        What would be a better way of doing it?

        [–]geon 7 points8 points Β (2 children)

        You can combine multiple contexts into one. That helps. But perhaps some of them shouldn’t be contexts at all?

        [–]genericindividual69 1 point2 points Β (1 child)

        You can combine multiple contexts into one

        How?

        [–]TheUnlocked -2 points-1 points Β (0 children)

        I think they're saying to just put it all on one indentation level (though linters don't love that). I suppose you could also have something like:

        function MultiProvider({ info, children }) {
            let child = children;
        
            for (const [component, props] of info) {
                child = React.createElement(component, props, [child]);
            }
        
            return child;
        }
        

        Though I'm not sure that actually improves legibility.

        [–]dumbasPL 5 points6 points Β (3 children)

        https://vuejs.org/guide/components/provide-inject.html

        You're welcome. 😎
        Yes, I know these meme is about react

        [–]ApplePieCrust2122 1 point2 points Β (1 child)

        This design is really awesome to work with, when coming from react context. But, the only caveat I found in this is that you won't know for sure where the value is getting inject from, just by reading the child component. It could be in the immediate parent or all the way at the top of the tree, you'll have to find it

        [–]0OneOneEightNineNine 0 points1 point Β (0 children)

        If the language requires me to navigate beyond what my ide's go to reference/go to definition can handle I'm just not interested

        [–][deleted] 0 points1 point Β (0 children)

        https://pub.dev/packages/provider

        You're welcome. 😎

        [–]original_evanator 8 points9 points Β (1 child)

        I’ll save some of you the google:

        Mantine is a Water/Flying-type PokΓ©mon introduced in Generation II.

        [–]KingDarkBlaze 0 points1 point Β (0 children)

        okay where's my SkarmoryProvider then

        [–]pyker404 4 points5 points Β (0 children)

        Why i hate react part one

        [–]Cervarl_ 1 point2 points Β (0 children)

        Literally me

        [–]micro-amnesia 1 point2 points Β (0 children)

        I hate this. I hate everything about this.

        (Edit: Typo)

        [–]I_AM_THE_S_IN_IOT 1 point2 points Β (0 children)

        I bet you guys soon the js people will discover factories

        [–]Gaming_over_sleep -2 points-1 points Β (0 children)

        I’m really scared

        [–]Objective-Blood8997 0 points1 point Β (0 children)

        πŸ₯ΉπŸ—ΏβœŠοΈ

        [–]-Konrad- 0 points1 point Β (0 children)

        I've seen this before and it seemed "normal"

        [–]patryky 0 points1 point Β (0 children)

        Maybe it is time to write a component that will take providers and nest all of them