For simple examples, I think this works really well. I'd argue for larger examples Context would work better. The solution with composition ends up creating a larger JSX tree at the top level, which again, is fine while it's small. The problem compounds as you continue to get components of components of components. I think in an ideal world there's a little bit of both. But I agree with what you're saying in theory - you don't need global state to avoid prop drilling.
Exactly my thoughts. Many apps are huge. I had the chance to use composition but I end up with many many nested components and it was awful to read and to find things quickly. One should use whatever it works for the problem at hand, and not to worry too much about "un/popular opinions".
This is just a technique, not intended to solve every situation! I just wanted to demo what it means to "use composition instead of context" in certain situations. I think that sentence is a bit difficult to digest if you're not familiar with the concepts.
I agree with Lee, the example is too simplistic - even in the example you used you also then need to pass the state setters down to the children elements, in your case LoginForm - what then happens if the login form itself is 3 or more children deep? Even though you are rendering components you end up defining most of the application in one place simply to avoid using context? It needs to be a combination of both composition and context. Users should be in context - there will rarely be only one child that needs it details - usually you will need the user to manage permissions as well. I think composition should be limited to anything that doesn't need to be outside of the current branch - like a dashboard tile, you would render a that makes sense, defining your content tree in doesn't.....
You did great here, when I first read the tweet I was very confused on how to use component composition instead of context and you made it so clear with this. Thank you so much.
This is great! My brain was already seeing that that Context seemed too much but I didn't tried composition until now. This surely will help me in killing that poor contexts. Seeing the comments I think this is the correct resume about using Composition vs Contexts: -Use Composition to solve simple (or shallow) prop drilling problems or to make components that can be composable and used in different places with some differences in the template. -Use Context when I really have some deep tree and this context is really need and used by many others components.
This video makes it just so easy to understand how to use component composition to get around prop drilling (and provide greater component flexibility). And only 15 mins! Thank you so much for putting this together.
This is a good video. My opinion on this is that your example works well because it's extremely basic in UI design (i.e. none). Breaking down components like this into Children is something I've done a lot of, however I stopped doing this (exclusively) because when it came time to make something more complex - *like a real application with a real UI* - composition just wasn't cutting it on its own. Thanks to Context, I was able to get a lot more done, with a lot less code, and it helps keep my components sane. I've never had an issue with using Context to store large sets of data for the entire app, even in production, which in my case needs to be used in multiple components - with no relation to each other, and also deeply nested. I also never had a rendering issue with Context when applied to all child components under the provider either. I am not worried about the re-renders from the props being passed to all elements, none of it is being written to the DOM unless actual data changes. Composition became a problem for me when the UI I was developing started getting complex in layout, and I had too much code in the main App.tsx file trying to create this layout. Doing it all by Composition put me in a mindset where I started breaking out ALL small chunks of elements into their own Components and it was becoming a huge mess because I was convinced this was the best way to solve an issue. I eventually got over it once the product I helped developed removed a lot of Composition and instead replaced a lot of with Context with absolutely zero issues. It's in production, everyone is happy, and the product is profitable (in the >$900k a month). The biggest benefit to this is: Less developer headaches, quicker development because we simply get the data we need, when we need it and where we need it. While the Composition reduces a lot of prop drilling, you're really just replacing it with a lot of Child nesting. Either way, nesting needs to be managed. Today I use a mix of both and never had any issues since.
I really like this. Composition makes a lot more sense when you want to share context across a set of components. Making things explicit increases maintainability and reduces potential bugs when components are reused.
Being able to pass state from the App component a few levels down is a great thing. I feel like this is going to help me fix a few issues with my code. Thanks for teaching this to us.
so by using composition we explicitly expose the children of a component and pass state directly to the child component that needs it. this was a great video , I learned about composition and useContext hook at the same time . great !
This works only when the component that needs the property is relatively shallow in the tree. What if the component that needs the user is 10 levels deep? Using compositions at the very top level would end up in cluttered code. BTW, having a "black box" component isn't necessarily a bad thing. It hides complexity at one level and reveals it at another. Isn't that part of the idea of components?
black box adds more complexity if you need composition (composition in this case means at some places you need to render it with a title, in some other without a title)
Great video Michael. Even though this example is simple I think it still applies in larger apps such as in places with smaller compositions. For larger compositions (maybe you should think about why it's large), you could consider using a layout/template component with slots (props that take components) that abstract away things that might be common between dashboards for example (taking from the example in the video). You might end up with one level of prop drilling but I think that is still a better tradeoff than using context. The issue I have with a child component relying on a bit of context is that it's not immediately obvious and you so need to examine the inner workings of a component to figure out, firstly that it needs context, what context it needs, and its shape. I'm still learning about when it's best to use context but generally, I consider it for cross-cutting concerns; which passing a value to a child component is not imho.
The "prop drilling" vs "use context" debate reminds me of "dependency injection" vs "static service locators" in the dotnet world. We often recoil at passing variables down complex dependency chains so we go back to using what are essentially global variables. This makes our components unintuitive and fragile. The complexity doesn't go away it's just hidden, but not in a helpful way where you don't have to think about it anymore.
my understanding in use of context and composition applied in projects: Composition is best one while it's being used in a component which has lots of presentational components that expects values as props. Looks more code you have in a file. It's worth for future updates. Context can be used on top of composition to get specific data (not all, we have state for it) from very high level or root in large scale applications. Thanks for explaining more use of context.
@@benlorantfy6179 Not really. By extracting that block into a component 'UserDashboard', the new component will directly be passing that user to WelcomeMessage. The concept is very similar to nested if conditions Vs combining conditions via AND into a single if. The result is a much simpler & easier to understand code without a stair of brackets. Take a look at React documentation showing a similar example for Dialog & SignupDialog: reactjs.org/docs/composition-vs-inheritance.html
The problem is that a lot of components are primarily useful because they know what to render given some data. If you have to pass a big tree of children into Dashboard every time you use Dashboard, it’s really not doing much for you. In this simplistic example, it’s just rendering a heading then rendering its children.
But at the same time, the dashboard is now responsible for all content within it without overly abstracting things away. You can clearly and cleanly see what you've got. I was skeptical but thinking about it again, it seems great. And if you do have some components that take props for their state, why don't you just give it only to those components that need it? You still have a clean structure and less prop drilling. It just doesn't make sense to give data to components that are just going to pass it on.
Good approach.Using children prop this way it's useful to make the father component more customizable in case you need to render different children depending the situation.Thanks.
Thanks for the vid. Composition is one more tool/pattern we can use when appropriate. The 'prop drilling' issue aside - sometimes it's useful to use a 'blackbox' approach - for example when consumers of your component do not need to know or want to know about it's internals. Sometimes as a dev all I care is that if I feed it x, y and z the component does it's job.
He's using `vim` in a very very dumb way, TBH. I use `vim` on a daily basis and I can tell you that I rarely use `hjkl` to move around ;), you see, the real power of `vim` relies on something called `text-objects` (open up vim and type :help text-object to have a better idea), a concrete example, when he removed the `{user}` inside the `WelcomeMessage` component he selected the whole text and, most likely, he pressed `x`, instead, the `vim way` dictates that you do `di(` and that's it!!, what that motion will do is `remove the things inside the parenthesis` :) that's how awesome `vim` is. Anyway, I know this may sound like a rant from a `vim zealot`, IT'S NOT, I've seen both Michael & Ryan using `vim`, they do need to improve! hahaha, but I'm glad that developers like them choose `vim` over something like `VSCode` and they even do that on Live conferences so... I admire both of them and it's very nice that they show off that to other developers and hopefully the jump into the `vim`, `emacs`, whatever.
@@NickNijenhuis I don't tell people what IDE/Text Editor they should use, that's something personal IMHO. I prefer vim/Emacs over something like VSCode, Intellij, etc because I feel very comfortable using them and, from experience and looking at how other people work, I can tell you that I'm 10x faster than them :), that doesn't mean I'm a superb person or anything, it's just that those tools don't require you to be raising your hand to open/close a sidebar to look for a file (shortcuts exist but when using GUI, for some reason, people forget about that).
Reposting my comment on Reddit here: This video has been very interesting to watch as someone with a background in C# and Angular. The problem here is exactly the same one dependency injection solves. What Michael does is extracting a dependency (`currentUser`) and manually assembling the composition root. Using Context would be what the DI world calls the service registry anti-pattern. I'm learning React right now and I find its simplicity refreshing. I would love to see if there are other ways of achieving dependency inversion in the React world. I honestly find the heavyweight approach of Java/C#/Angular DI containers distasteful.
If you use something like redux you get inversion of control out of the box without the need for di only because dicision making is abstracted away from all your components and the only things your components get injected with are actual data and callbacks
Super useful! (for others, I've been in this situation, but as I am still getting used to react, all of that context (no pun inteded) was actually really useful)
Great video that shows how to implement composition. I’ve recently started using React for a small work application and I’m loving it. For a small chain of components, prop drilling works fine. But it gets confusing with a larger chain. I’m going to try composition the next time I get into a mess with prop drilling haha. I’d rather see the pros/cons of prop drilling and composition before using Redux in my current application.
One use case I thought about who makes composition more ineficient than Context is, if WelcomeMessage depends on props which are defined by DashboardContent you could not use composition without using renderProps. Which is leaking internal mechanics of DashboardContent.
Thanks for an interesting video and some fresh thoughts. I subscribed on the strength of it. I agree with your point about not liking the implicitness of context. Correct me if I'm wrong, but the main trade-off I'm seeing with the approach you outlined is that the parent (or grand-parent) component now needs to know more about the shape of its child components, i.e. there is less abstraction and more information leakage across boundaries. The "Law" of Demeter comes to mind en.wikipedia.org/wiki/Law_of_Demeter
Very informative tutorial on how to avoid Prop-Drilling or Context by using Composition. Thanks very much, Michael {2022-03-14}, {2023-05-25}, {2023-07-22}
I just tried refactoring out some useReducer-useContext stuff to make my components more composable. 👏🏾. I did lose a few components that were kind of pointless and did eliminate the need to create 'global state' via reducer-context. Henceforth, I will stive to think 2x about whether or not said state REALLY is global in nature before I reach for reducer-context (and still will probably never use Redux).
Thanks for the opinion, you definitely show an alternative pattern for avoiding prop drilling and context, but I’m not a fan how the app file defines the sub-components of dashboard, it makes more sense to call them from a dashboard component which would probably be a separate container file anyway
Maybe because I am a newbie about all this react workflow. But a lot of comments talking about huge apps. I am a really bad at visual design, but my strong suit is data design. How deep do they need the children on a tree of components? Are you sure that is the right way to go? I would say if it is 7 levels deep in your DOM hierarchy and you still need passing props, watch out!!! And 7 levels is already making my data display itchy. Even on advanced platforms like your own profile administrator on Google or a Spreadsheet software (MS Excel, libreoffice calc), you do not get to 6 levels or more, and if you do is for really specific cases. So I'm on board with this and for me is going to be the way I will be making my react apps, taking into account that I will be using tanstak react query to help me with the cache of server-state.
the problem with context is its impurity, it makes component reusability harder, and produces unpredictability as you don't have the same output for the same props on a component (because context can change)
I think I get where you are coming from. A lot of people are asking about components nested 5, 6, 10 layers deep, and I think there's rarely a need to go beyond 4 layers of abstraction. Atomic component design has 4 layers in it, atoms, molecules, organisms, and pages (also templates). This component design philosophy is rooted in composition. atoms are composed to make molecules, which are composed to make organisms and so on. With proper composition, colocation of state, and thoughtful abstraction you can build any modern web application. In cases where you want to know about the meta state of the app (theme, scroll position, current location, etc...) then context can be helpful because it's already a global state.
This is more a component architecture than an app architecture. If user was being used on multiple pages and you needed to update user in some places, your example here doesn't fly. So i think when pages need to share context and do data manipulation, it's nice to have that in one place in the context. If you want to avoid the issue of components using the context then you let the page read the context and expose the data and methods to your components as you have shown here with composition. That way you have the best of both worlds. Try stay away from using context in components and keep it at page level. Cause then you have a nice overview of what your page is trying to achieve. Overtime your context will get bloated and there's no code splitting on the context, react bundles your entire context into the app.js file whether you are using methods in it or not. So be careful of that.
Correct me if I’m missing something but every time you use Dashboard, you’d need to pass all of it’s children. You’d be rewriting a whole bunch of code (the children) every time which kind of misses the whole point if components? Also, I think there’s more room for error here (forgetting to pass currentUser to a child of a given instance of the Dashboard) than just simply using context or Redux
It all depends on the context of usage. If you have a different dashboards this approach that he presents is actually good one, and doesn't miss the whole point of components, on the contrary - it utilizes it. Dashboard may have some different operations inside, like "save to pdf" and it will take the children prop to perform such operation. This is actually really good pattern for some cases. But as always with writing code - you need to think what actually is good approach for your purpose.
New to React, not new to programming. I think the React best practices include 1) Children first, 2) Composition second, 3) Context third. Global variables should be avoided (common rule to all languages)
Makes sense. I am just wondering about the case when more than one prop is really needed for nested components that are placed not near each other (say at the top and at the bottom of the component). In that case, using that mechanism would mean to have more stuff passed to the children which may be too much effort just to get rid of the context.
I don't totally agree here, this approach may work for this example but in a real project it will create a huge complexity, imagine a high-level component has to know about the exact detail of a low-level component (e.g: the order of rendering components in the DashboardContent) then if something needs to be changed in DashboardContent your changes would be on AppComponent which doesn't make sense, this approach has put all the other component's responsibility on a high-level components shoulders for the sake of not using context. In another word, you will end up having too much unnecessary code and huge component files that are defining nested components that are totally out of their responsibility. in this example, the AppComponent responsibility is to navigate the user to the correct section of the app based on the authentication status the rest is not its concern but it ends up rendering a welcome message, which violates the separation of concerns principle. also, this component should do one and only one job which is doing more, that is a violation of the single responsibility principle Recap: the objection to components ambiguity is valid but the solution is making a bigger problem.
You say this pattern addresses the hypothetical problem of accidentally putting a component outside of the context it needs. I fail to see how that is meaningfully different from accidentally composing a component in the wrong place. Especially for a user context which should simply wrap the entire application. The other problem you bring up is what happens if user is undefined? Again I don't see how composition and props actually addresses this problem. If user data has to be retrieved, whether you use context or not has no impact on handling the logic of whether you've found a user. However, I do think this effectively illustrated what component composition looks like and how flexible react is when you learn to use children. Thanks for contributing to the conversation and please explain any disagreements you have with my points!
Yes! I need to use that more often. I've gotten accustomed to using dib which deletes inside the nearest set of braces, but in the case of ({ user }) it would change it to ({}) and leave me with the curlies. I need to not be lazy and reach for the (
@@ReactTraining didn't know about dib, thanks :D For that case I also use da}. Also, learning some more motions (e, B, W, etc.) would speed you up. I learned a lot playing vimgolf.com
@@ReactTraining You might have a plugin that is causing that behaviour-or possibly accidentally hit shift+b once and never looked back-but out of the box, dib targets () and diB targets {}.
Good explanation... But even in this example (14:22) we are getting wrappers hell. It's better to use context with one condition: it should be isolated by its context - and it's not a big problem really.
Relying on the discipline of co-workers to use higher order components seems like a bad bet, I'd consider a Fulcro or Om Next pattern to make this a non issue again
This is so obvious of an approach since HTML has been working like this for ages... Something went wrong in people minds. I wonder though if it is possible to pass down a few children and put each one in particular slot inside jsx of a component children are passed to.
For simple examples, I think this works really well. I'd argue for larger examples Context would work better. The solution with composition ends up creating a larger JSX tree at the top level, which again, is fine while it's small. The problem compounds as you continue to get components of components of components.
I think in an ideal world there's a little bit of both. But I agree with what you're saying in theory - you don't need global state to avoid prop drilling.
Exactly my thoughts. Many apps are huge. I had the chance to use composition but I end up with many many nested components and it was awful to read and to find things quickly.
One should use whatever it works for the problem at hand, and not to worry too much about "un/popular opinions".
You can create container components for handling the big markup, but Composition just feels the right way, IMO.
Agreed with Lee
This is just a technique, not intended to solve every situation! I just wanted to demo what it means to "use composition instead of context" in certain situations. I think that sentence is a bit difficult to digest if you're not familiar with the concepts.
I agree with Lee, the example is too simplistic - even in the example you used you also then need to pass the state setters down to the children elements, in your case LoginForm - what then happens if the login form itself is 3 or more children deep? Even though you are rendering components you end up defining most of the application in one place simply to avoid using context? It needs to be a combination of both composition and context. Users should be in context - there will rarely be only one child that needs it details - usually you will need the user to manage permissions as well. I think composition should be limited to anything that doesn't need to be outside of the current branch - like a dashboard tile, you would render a that makes sense, defining your content tree in doesn't.....
Great video! Although your keyboard drilled my ears more than props to my component 🤣
Same here, but after i while i find it quite satisfying 🤣
My thoughts exactly! He's mean to his keyboard 😂
Thanks for making this so clear, I also always felt children pattern is most powerful feature of React and underrated too.
You did great here, when I first read the tweet I was very confused on how to use component composition instead of context and you made it so clear with this. Thank you so much.
This is great! My brain was already seeing that that Context seemed too much but I didn't tried composition until now. This surely will help me in killing that poor contexts.
Seeing the comments I think this is the correct resume about using Composition vs Contexts:
-Use Composition to solve simple (or shallow) prop drilling problems or to make components that can be composable and used in different places with some differences in the template.
-Use Context when I really have some deep tree and this context is really need and used by many others components.
This video makes it just so easy to understand how to use component composition to get around prop drilling (and provide greater component flexibility). And only 15 mins! Thank you so much for putting this together.
This is a good video. My opinion on this is that your example works well because it's extremely basic in UI design (i.e. none). Breaking down components like this into Children is something I've done a lot of, however I stopped doing this (exclusively) because when it came time to make something more complex - *like a real application with a real UI* - composition just wasn't cutting it on its own.
Thanks to Context, I was able to get a lot more done, with a lot less code, and it helps keep my components sane. I've never had an issue with using Context to store large sets of data for the entire app, even in production, which in my case needs to be used in multiple components - with no relation to each other, and also deeply nested. I also never had a rendering issue with Context when applied to all child components under the provider either. I am not worried about the re-renders from the props being passed to all elements, none of it is being written to the DOM unless actual data changes.
Composition became a problem for me when the UI I was developing started getting complex in layout, and I had too much code in the main App.tsx file trying to create this layout. Doing it all by Composition put me in a mindset where I started breaking out ALL small chunks of elements into their own Components and it was becoming a huge mess because I was convinced this was the best way to solve an issue.
I eventually got over it once the product I helped developed removed a lot of Composition and instead replaced a lot of with Context with absolutely zero issues. It's in production, everyone is happy, and the product is profitable (in the >$900k a month). The biggest benefit to this is: Less developer headaches, quicker development because we simply get the data we need, when we need it and where we need it.
While the Composition reduces a lot of prop drilling, you're really just replacing it with a lot of Child nesting. Either way, nesting needs to be managed.
Today I use a mix of both and never had any issues since.
I really like this. Composition makes a lot more sense when you want to share context across a set of components. Making things explicit increases maintainability and reduces potential bugs when components are reused.
Being able to pass state from the App component a few levels down is a great thing.
I feel like this is going to help me fix a few issues with my code.
Thanks for teaching this to us.
so by using composition we explicitly expose the children of a component and pass state directly to the child component that needs it. this was a great video , I learned about composition and useContext hook at the same time . great !
Four years later, this saved my day! Thanks.
Thanks for showing how to implement Composition. Now would be able to use both according to condition.
This works only when the component that needs the property is relatively shallow in the tree. What if the component that needs the user is 10 levels deep? Using compositions at the very top level would end up in cluttered code.
BTW, having a "black box" component isn't necessarily a bad thing. It hides complexity at one level and reveals it at another. Isn't that part of the idea of components?
black box adds more complexity if you need composition (composition in this case means at some places you need to render it with a title, in some other without a title)
Great video Michael. Even though this example is simple I think it still applies in larger apps such as in places with smaller compositions. For larger compositions (maybe you should think about why it's large), you could consider using a layout/template component with slots (props that take components) that abstract away things that might be common between dashboards for example (taking from the example in the video). You might end up with one level of prop drilling but I think that is still a better tradeoff than using context. The issue I have with a child component relying on a bit of context is that it's not immediately obvious and you so need to examine the inner workings of a component to figure out, firstly that it needs context, what context it needs, and its shape. I'm still learning about when it's best to use context but generally, I consider it for cross-cutting concerns; which passing a value to a child component is not imho.
The video helps me understand the difference between the Context and the function composition. Thanks a lot.
A very simple example to understand the scenario where we need to use context and component composition.
Thank you for this explanation.
Thanks Jordan for this video. It really gave me a different view when dealing with props in components.
The "prop drilling" vs "use context" debate reminds me of "dependency injection" vs "static service locators" in the dotnet world. We often recoil at passing variables down complex dependency chains so we go back to using what are essentially global variables. This makes our components unintuitive and fragile. The complexity doesn't go away it's just hidden, but not in a helpful way where you don't have to think about it anymore.
my understanding in use of context and composition applied in projects:
Composition is best one while it's being used in a component which has lots of presentational components that expects values as props.
Looks more code you have in a file. It's worth for future updates.
Context can be used on top of composition to get specific data (not all, we have state for it) from very high level or root in large scale applications.
Thanks for explaining more use of context.
This is great understanding! Good thinking dude!
This has given me a new perspective - thank you!
Best video on the topic ...just Excellent!!
Very clear video about where to use context and where to use composition. Thanks!
If you need to place this composite dashboard in several places, you will encounter code duplication.
You could wrap the dashboard block in a separate component which accepts the user prop
@@CanRau Then you're back with the original problem
@@benlorantfy6179 Not really. By extracting that block into a component 'UserDashboard', the new component will directly be passing that user to WelcomeMessage. The concept is very similar to nested if conditions Vs combining conditions via AND into a single if. The result is a much simpler & easier to understand code without a stair of brackets.
Take a look at React documentation showing a similar example for Dialog & SignupDialog: reactjs.org/docs/composition-vs-inheritance.html
The problem is that a lot of components are primarily useful because they know what to render given some data. If you have to pass a big tree of children into Dashboard every time you use Dashboard, it’s really not doing much for you. In this simplistic example, it’s just rendering a heading then rendering its children.
I think you can make specific Dashboard then. Like or which has different children structure. See reactjs.org/docs/composition-vs-inheritance.html
But at the same time, the dashboard is now responsible for all content within it without overly abstracting things away.
You can clearly and cleanly see what you've got. I was skeptical but thinking about it again, it seems great.
And if you do have some components that take props for their state, why don't you just give it only to those components that need it?
You still have a clean structure and less prop drilling.
It just doesn't make sense to give data to components that are just going to pass it on.
Or create a design system with compound components using the same methods and Walla… little to no props visible in the main app.
Very clear and concise! I will have the composition pattern in mind next time! thx for sharing
Thank you for the video. It was instructive.
Good approach.Using children prop this way it's useful to make the father component more customizable in case you need to render different children depending the situation.Thanks.
It has been like 5 years that React released Open source, and we still don't know how to use the basics. Thank you for remembering us that! Cheers
Thanks for the vid. Composition is one more tool/pattern we can use when appropriate. The 'prop drilling' issue aside - sometimes it's useful to use a 'blackbox' approach - for example when consumers of your component do not need to know or want to know about it's internals. Sometimes as a dev all I care is that if I feed it x, y and z the component does it's job.
Thank you. Now I understand what component composition is.
i need a React Training vim course
Do you mean something about how to best utilize vim while developing React?
@@someonlinevideos vim course by React Training ; ] ... btw I do too lol
He's using `vim` in a very very dumb way, TBH. I use `vim` on a daily basis and I can tell you that I rarely use `hjkl` to move around ;), you see, the real power of `vim` relies on something called `text-objects` (open up vim and type :help text-object to have a better idea), a concrete example, when he removed the `{user}` inside the `WelcomeMessage` component he selected the whole text and, most likely, he pressed `x`, instead, the `vim way` dictates that you do `di(` and that's it!!, what that motion will do is `remove the things inside the parenthesis` :) that's how awesome `vim` is.
Anyway, I know this may sound like a rant from a `vim zealot`, IT'S NOT, I've seen both Michael & Ryan using `vim`, they do need to improve! hahaha, but I'm glad that developers like them choose `vim` over something like `VSCode` and they even do that on Live conferences so... I admire both of them and it's very nice that they show off that to other developers and hopefully the jump into the `vim`, `emacs`, whatever.
@@RubenGarcia-mr7pe Why do you like people using VIM over VSCode?
@@NickNijenhuis I don't tell people what IDE/Text Editor they should use, that's something personal IMHO. I prefer vim/Emacs over something like VSCode, Intellij, etc because I feel very comfortable using them and, from experience and looking at how other people work, I can tell you that I'm 10x faster than them :), that doesn't mean I'm a superb person or anything, it's just that those tools don't require you to be raising your hand to open/close a sidebar to look for a file (shortcuts exist but when using GUI, for some reason, people forget about that).
Wow!!! this was very useful,
Thank you very much
So simple but it blew my mind. Thanks for this amazing tip. I'm going to go and refactor some code now :)
Amazing solution, thank you
nit: put border on each component so that composition is emphatically visible.
Reposting my comment on Reddit here:
This video has been very interesting to watch as someone with a background in C# and Angular. The problem here is exactly the same one dependency injection solves. What Michael does is extracting a dependency (`currentUser`) and manually assembling the composition root. Using Context would be what the DI world calls the service registry anti-pattern.
I'm learning React right now and I find its simplicity refreshing. I would love to see if there are other ways of achieving dependency inversion in the React world. I honestly find the heavyweight approach of Java/C#/Angular DI containers distasteful.
If you use something like redux you get inversion of control out of the box without the need for di only because dicision making is abstracted away from all your components and the only things your components get injected with are actual data and callbacks
Thanks .. learned something new!
Great to change the angle with which we approach things, thanks
Thanks for this tutorial, it was great to discover this pattern.
Great video. Thanks!
10:02 to skip to context and jump right into composition example
Thank you
Super useful! (for others, I've been in this situation, but as I am still getting used to react, all of that context (no pun inteded) was actually really useful)
thank you
Very interesting, thanks!
great video man, very clear and direct to the point
Great video that shows how to implement composition. I’ve recently started using React for a small work application and I’m loving it. For a small chain of components, prop drilling works fine. But it gets confusing with a larger chain.
I’m going to try composition the next time I get into a mess with prop drilling haha. I’d rather see the pros/cons of prop drilling and composition before using Redux in my current application.
Not sure I agree here fully but gave thumbs up because of the great explanation of your thought process. Also subbed!
One use case I thought about who makes composition more ineficient than Context is, if WelcomeMessage depends on props which are defined by DashboardContent you could not use composition without using renderProps. Which is leaking internal mechanics of DashboardContent.
Thanks for an interesting video and some fresh thoughts. I subscribed on the strength of it.
I agree with your point about not liking the implicitness of context. Correct me if I'm wrong, but the main trade-off I'm seeing with the approach you outlined is that the parent (or grand-parent) component now needs to know more about the shape of its child components, i.e. there is less abstraction and more information leakage across boundaries. The "Law" of Demeter comes to mind en.wikipedia.org/wiki/Law_of_Demeter
Very informative tutorial on how to avoid Prop-Drilling or Context by using Composition. Thanks very much, Michael
{2022-03-14}, {2023-05-25}, {2023-07-22}
Very good explanation! Thank you
Thanks, a very good video.
redirected from epicreactdev, discovered a past me already liked the video.
That cleared that up really well for me; thank you :)
Super helpful video, thanks!
Thanks for explain.
very clearly explained. subscribed.
Fabulous tutorial. Thank you very much, very useful.
Context is my best friend :)
I just tried refactoring out some useReducer-useContext stuff to make my components more composable. 👏🏾. I did lose a few components that were kind of pointless and did eliminate the need to create 'global state' via reducer-context.
Henceforth, I will stive to think 2x about whether or not said state REALLY is global in nature before I reach for reducer-context (and still will probably never use Redux).
Thanks for the opinion, you definitely show an alternative pattern for avoiding prop drilling and context, but I’m not a fan how the app file defines the sub-components of dashboard, it makes more sense to call them from a dashboard component which would probably be a separate container file anyway
Nailed it!
Excellent tutorial!
Taking this into consideration, I guess you would reach out for redux even less then for context right?
excellent video! very informative
Thank you
thank you!
Great video. Also, neat Vim skills.
Great video, thank you!
It is not useful, it is awesome! Thanks for sharing!
May I ask what plugin is that that gives the ending tags a different color? I really like it. Makes the code easier to read.
wow amazing this is really cool!
would love to see when should i use context or redux
Maybe because I am a newbie about all this react workflow. But a lot of comments talking about huge apps. I am a really bad at visual design, but my strong suit is data design. How deep do they need the children on a tree of components? Are you sure that is the right way to go? I would say if it is 7 levels deep in your DOM hierarchy and you still need passing props, watch out!!! And 7 levels is already making my data display itchy. Even on advanced platforms like your own profile administrator on Google or a Spreadsheet software (MS Excel, libreoffice calc), you do not get to 6 levels or more, and if you do is for really specific cases. So I'm on board with this and for me is going to be the way I will be making my react apps, taking into account that I will be using tanstak react query to help me with the cache of server-state.
Thanks for this video, what if WelcomeMessage needs also some data coming from DashboardCompononent?
This is great but also what extension makes your closing tag a different color?!
the problem with context is its impurity, it makes component reusability harder, and produces unpredictability as you don't have the same output for the same props on a component (because context can change)
great insights thank you
I think I get where you are coming from.
A lot of people are asking about components nested 5, 6, 10 layers deep, and I think there's rarely a need to go beyond 4 layers of abstraction. Atomic component design has 4 layers in it, atoms, molecules, organisms, and pages (also templates). This component design philosophy is rooted in composition. atoms are composed to make molecules, which are composed to make organisms and so on.
With proper composition, colocation of state, and thoughtful abstraction you can build any modern web application. In cases where you want to know about the meta state of the app (theme, scroll position, current location, etc...) then context can be helpful because it's already a global state.
Great video :)
Great content man.
This is more a component architecture than an app architecture.
If user was being used on multiple pages and you needed to update user in some places, your example here doesn't fly.
So i think when pages need to share context and do data manipulation, it's nice to have that in one place in the context.
If you want to avoid the issue of components using the context then you let the page read the context and expose the data and methods to your components as you have shown here with composition. That way you have the best of both worlds.
Try stay away from using context in components and keep it at page level. Cause then you have a nice overview of what your page is trying to achieve.
Overtime your context will get bloated and there's no code splitting on the context, react bundles your entire context into the app.js file whether you are using methods in it or not. So be careful of that.
Correct me if I’m missing something but every time you use Dashboard, you’d need to pass all of it’s children. You’d be rewriting a whole bunch of code (the children) every time which kind of misses the whole point if components? Also, I think there’s more room for error here (forgetting to pass currentUser to a child of a given instance of the Dashboard) than just simply using context or Redux
It all depends on the context of usage. If you have a different dashboards this approach that he presents is actually good one, and doesn't miss the whole point of components, on the contrary - it utilizes it. Dashboard may have some different operations inside, like "save to pdf" and it will take the children prop to perform such operation. This is actually really good pattern for some cases. But as always with writing code - you need to think what actually is good approach for your purpose.
Very nice example :)
That’s cool. I forgot about composition. There is an issue though, this only works if you have nested components. Unless I’m wrong
New to React, not new to programming. I think the React best practices include 1) Children first, 2) Composition second, 3) Context third. Global variables should be avoided (common rule to all languages)
Thanks for sharing! 👍🏾
Nice video
Makes sense. I am just wondering about the case when more than one prop is really needed for nested components that are placed not near each other (say at the top and at the bottom of the component). In that case, using that mechanism would mean to have more stuff passed to the children which may be too much effort just to get rid of the context.
Old good slot pattern. But quite hard to making use of it in complex component compositions.
I don't totally agree here, this approach may work for this example but in a real project it will create a huge complexity, imagine a high-level component has to know about the exact detail of a low-level component (e.g: the order of rendering components in the DashboardContent) then if something needs to be changed in DashboardContent your changes would be on AppComponent which doesn't make sense, this approach has put all the other component's responsibility on a high-level components shoulders for the sake of not using context. In another word, you will end up having too much unnecessary code and huge component files that are defining nested components that are totally out of their responsibility.
in this example, the AppComponent responsibility is to navigate the user to the correct section of the app based on the authentication status the rest is not its concern but it ends up rendering a welcome message, which violates the separation of concerns principle. also, this component should do one and only one job which is doing more, that is a violation of the single responsibility principle
Recap: the objection to components ambiguity is valid but the solution is making a bigger problem.
some will argue using context for something this simple is overengineering. I, a simple man do not see it that way. Context for the win
you are good, thanks
One Tree to Rule Them All
You say this pattern addresses the hypothetical problem of accidentally putting a component outside of the context it needs. I fail to see how that is meaningfully different from accidentally composing a component in the wrong place. Especially for a user context which should simply wrap the entire application.
The other problem you bring up is what happens if user is undefined? Again I don't see how composition and props actually addresses this problem. If user data has to be retrieved, whether you use context or not has no impact on handling the logic of whether you've found a user.
However, I do think this effectively illustrated what component composition looks like and how flexible react is when you learn to use children. Thanks for contributing to the conversation and please explain any disagreements you have with my points!
Vim's di( might help delete some of those props. :D
Yes! I need to use that more often. I've gotten accustomed to using dib which deletes inside the nearest set of braces, but in the case of ({ user }) it would change it to ({}) and leave me with the curlies. I need to not be lazy and reach for the (
@@ReactTraining didn't know about dib, thanks :D For that case I also use da}. Also, learning some more motions (e, B, W, etc.) would speed you up. I learned a lot playing vimgolf.com
@@ReactTraining You might have a plugin that is causing that behaviour-or possibly accidentally hit shift+b once and never looked back-but out of the box, dib targets () and diB targets {}.
Thank you.
Thank you!
Good explanation... But even in this example (14:22) we are getting wrappers hell. It's better to use context with one condition: it should be isolated by its context - and it's not a big problem really.
Relying on the discipline of co-workers to use higher order components seems like a bad bet, I'd consider a Fulcro or Om Next pattern to make this a non issue again
This is so obvious of an approach since HTML has been working like this for ages... Something went wrong in people minds.
I wonder though if it is possible to pass down a few children and put each one in particular slot inside jsx of a component children are passed to.