Definitive Guide to React Component Design and the key to avoiding tech debt

preview_player
Показать описание
Instead of building up tons of tech debt with React, I'll teach you how to build better, more-flexible React components using "children-first" design principles! It's a combination of compound components (a lost art) and context.

Through years and years of coding day and night, I bring to you, a Definitive Guide to React Component Design; a set of skills and principles you could use for coding even outside of React.

Children-first components:

This talk is about avoiding tech debt to make you a better developer.

Other similar terms are "React Clean Architecture", "React Design Patterns", "React Best Practices", and "Junior vs Senior code".
Рекомендации по теме
Комментарии
Автор

I've been searching for content to improve my shitty React codebase, and out of about 10 way more popular videos, this is the first one with some actual content. Others just tell something basic without any convincing. But your video is so much better! A bit long, so I'll watch the rest later, plus I see you left long answers to comments, which I'll obv have to read now. But for now, thanks!

mks-h
Автор

Your work are truly amazing! I known about compound component a couple months ago, I think it's really cool concept till I watched this video that you show even cooler concept. Thank!

minhquoctran
Автор

I think the weakness of moving a lot of logic to context, is that it creates an implicit coupling to the component hierarchy. Context providers need to be always on top of context consumers. There can be a case, where you want to use a child component without a ctx provider, but it's not possible with this approach. This point is also mentioned in react docs about context Api, where they prioritise component composition over context api.

Second, there there is an argument to be made about readability. With prop drilling, you are at least writing explicitly how data flows through the component hierarchy. I think excessive ctx api usage has a bigger potential to become spaghetti (that's a highly opinionated argument, but still).

I personally come from Vue background and Vue also has its context Api alternative, called provide/inject. And it's *explicitly* meant to be used as an escape hatch, when you see it's the only solution possible. So I'm probably biased here.


My solution would be something like this:

1. Hooks don't have that issue, so I personally try to use them over provider / consumer pattern. Composition > Inheritance

2. The 'children-first' approach you mention certainly solves half of the problems, and don't have any coupling between components + avoids props, so I'm 100% with you on that one.

3. In some cases, you need to specify, that some component needs to be above another one, like in the AccordionRoot / AccordionItem example. So here, the context api is certainly cool, because there's no way you'll put AccordionItem above AccordionRoot. To move explicit, I really like to use the compound pattern, where you'd write a component like this:

<Accrdion.Root>
<Accrdion.Item> foo <Accrdion.Item>
</Accrdion.Root>

So it's extra explicit about the fact that these two components belong together, and it'll probably break if you use one, without the other. It's also what tailwind uses in the headless ui a lot.


In general, the cleanness of code is in the eyes of the beholder often, and the number 1 thing we all try to avoid is 50+ props drilling 6 levels deep. And the difference of HOW to do that can be often a thing of preference

_vay
Автор

Hey man this is a gold mine of information. Keep it up. You should do more videos in this style with the slides.

The way I learn most is when I get a short explanation of what a library/concept is first, why you need it, and why you should care. Then I like seeing an actual concrete example of how things are done using framework/example A and how the equivalent thing is done in framework/example B. Then I have the full context and can actually understand how example B solves the problems in example A and why I should even care in the first place. (think class + lifecycle vs function + hooks).

This way you can gradually build on example A and B as you continue through the video and you can also isolate sections of code from example A, B or even C without needing to give full context of each to get your point across.

I think this way is pretty digestible for most people and it makes sure the viewer is not lost in the middle of an explanation and they can discover why something is so elegant themselves.

Anyways, liked and subbed hope to see more soon.

keelangibb
Автор

Thanks a lot for this, as a beginner/intermediate software developer this kind of content that goes beyond usual YouTube's material is really valuable to level up.

I went ahead on my editor to try to implement the child first pattern with cloneElem and Context but if I may suggest something I think that this format suits well for conferences but a slightly more decoupled format within several videos with executed code examples to compare the different approaches might suits YouTube better and be more accessible.

heroe
Автор

Awesome! Worth watching over and over again. Would be even better if having subtitles.

lightyagami
Автор

Hey, I've enjoyed the talk, especially until 20:00. The thing about your children first design is that it's very different from what we (as frontend devs) are used to.
The problem with that is that it would be hard to get others to do it. And most importantly - they might not understand it. They might completely butcher a completely fine and reusable component. This is what I'm worried about with this approach.
I've seen trunk based development and functional programming - two very good approaches in my opinion - ruin a workflow or a code, because of one or two people who didn't know what they were doing. And that's not because they were a new programmer, it's just that they were not used to the nuanses in a codebase.
Again, I loved the talk, and I don't want to sound overly negative. I might give it a try, but it's possible that I will go with a more common approach c:

pawekoaczynski
Автор

Hi Kevin, great video. Strange I didn't find it earlier.

One question: you mention that using className prop is an anti-pattern.
What would be the right way to change the style of a component from the parent?

I could not find any good article about this and to be frank a lot of articles on the net are actually about using the className prop.

danielgreen
Автор

First 10 minutes: never heard components explained better

AlexanderBelov-yo
Автор

Amazing talk, could have used a bridge to the various styles of state managers (single store, local store), but enjoyed it a lot. Thank you for taking the time !

dinoscheidt
Автор

IMHO the technical part of explaining what is props and children was good. The part that's crazy to me is the obsession to make things more complicated that it needs to be. The take in this video is that you should take the responsibility that the other devs gonna produce bad code and the solution is to write a complex and difficult to read code to mitigate it.

eukursg
Автор

Your example of Accordion could be simplified by using data- and ARIA attributes to annotate your components and make them semantically correct, make them stylable and easy to test. The component itself doesn't need to know any styling, except for maybe orientation, which also can affect behaviour. There's no need for cloneElement here, so implementation is simpler, too.

ARIA attributes are often missed. By themselves ul and li does not represent an accordion, it represents a bullet point list semantically. Accordion, as the name suggests, visually collapse and expand sections. Sections have headings and a body, which does not fit the semantics of unordered lists, which are typically just content.

You may as well use divs and ARIA attributes to properly specify state, labels and roles for the content. Using ARIA labels to annotate the behaviour and state of a component is important for accessibility. Additionally you can select those ARIA attributes in CSS based on the state, for free. Data attributes are useful to give meaning to the component outside of it and without leaking abstractions.

It makes your components simpler to use, more accessible and makes it easily testable in E2E tests without leaking implementation details. It's all in the DOM.

dealloc
Автор

Great talk! but if you're not going to show the code for a lot of these examples, I think a link to a github repo would be helpful

Nicopellerin
Автор

this is the kind of video I wanted to see when googling "advanced react patterns". I only got all those generic ass videos explaining low or medium level react concepts over and over again.

oemeraran
Автор

I love the way you have dived deep into design patterns, but one main thing I am unsure about is that in the docs react team has mentioned not to use cloneElement and they have deprecated the api as well . So what’s your take on that? Would love to hear

pranavdhamanage
Автор

This is what real HTML programming looks like!

wvovaw
Автор

I'm still digesting this. I think in general I agree with a lot. I'm the one making the stink of using good patterns and avoiding tech debt at my company. A lot of my coworkers can see tech debt after the fact, but they can't see the actual cause. It's usually just, "we couldn't predict that this is what we'd have to do." Sure, that's true in some cases, but you can still maintain a lot of flexibility. And this talk showcases that with your building blocks concept.

cloneElement frankly scares me lol. I think its biggest strength is also its biggest weakness: that to the consumer, it's "magic" that "just works." I agree that I shouldn't care *how* something I'm using works, just how *I* need to use it. I think I get how you're using it here though. At first I thought you were doing the compound component pattern with that, but it seems you're doing that with context where appropriate. There are certainly situations where there could be another layer between a parent part of a compound component and a child part. But using components that clone their children to inject props is certainly interesting. It's like a more declarative HOC that can also be used inline. I know you don't use Typescript, but I'm curious if there's a way to type this. Probably is. Like "I need an instance of a component that could take this prop." I think it'd be something like ReactElement<{ onClick: () => void }>.

As someone else mentioned, I would also like to see examples with more depth. I don't know if you could write up a gist or something. I know coming up with examples that imitate real world use cases can be difficult, but with the video format and the slides only containing so much information, it's hard to keep a mental image of what the code might look like.

wesleynewcomb
Автор

Very interesting video. But the code snippets are quite hard to follow without full code samples.

bart
Автор

This is great, what I don't quite get is how does the <ModalTrigger> make the <button> inside it trigger the event needed for the logic of the modal? Does it clone the child with an extra onClick prop inserted somehow?

AlphaHydrae
Автор

any plans on doing a course or gettin back with the content? greetins from brazil ;)

favanzzo