3 ms·
Class components are fine for the simplest examples, but the moment they start increasing in complexity, they become a bit of a mess. Sharing functionality acro
by thatswrong0 5y ago
Class components are fine for the simplest examples, but the moment they start increasing in complexity, they become a bit of a mess. Sharing functionality across multiple components becomes tricky with class components (with the only real option being HoCs / render props). You necessarily have to spread logic across different lifecycle methods.
Hooks allow you to bundle code together by functionality, and consequently allow you to easily extract and share said functionality in a very composable way.
This is my go to for visualizing the difference: https://i.imgur.com/e9K8vfz.gif https://i.imgur.com/e9K8vfz.gif
- ctvo 5y ago> Hooks allow you to bundle code together by functionality, and consequently allow you to easily extract and share said functionality in a very composable way. You’re using React. The mechanism that enables code reusability is through composing components. There’s nothing wrong with class components even for the most complex logic. The only downside is the community has moved on and mostly adopted hooks and functional components.
- thatswrong0 5y ago> The mechanism that enables code reusability is through composing components If you think that this: return ( <Apple> {({ apple }) => ( <Slicer slice={apple}> {({ sliced: slicedApple } => ( <DinnerPlane contents={slicedApple} /> ) } </Slicer> )} </Apple> ); is more desirable than this: const apple = useApple(); const slicedApple = useSlicer(apple); return <DinnerPlate contents={slicedApple} />; Then go for it I guess. Although you'd have to somehow ignore the fact that you'd end up with an even bigger mess if you want these intermediate functionality steps to interact with the parent component in a non-trivial way, .. Needless to say, I have written such render-prop and "renderless" components in the past, and I see very little upside compared to hooks.
- masterofmisc 5y agoThats interesting. So in your 2nd example, am I right in saying the variables 'apple' and 'slicedApple' are react JSX that you are ultimatly passing through to <DinnerPlate/> to render on the screen? If so, yes, that is fairly intuitive.
- thatswrong0 5y ago'apple' and 'slicedApple' would more likely be strings / objects / arrays in the real world. Maybe this still woefully contrived version is clearer? function FacebookComment({ commentId }) { const comment = useGetComment(commentId); const likes = useGetLikes(comment); return ( <div> <span>{comment.text}</span> <span>{likes.length} likes</span> </div> ); } I don't think deal with more braces right now to bring the alternative into existence unfortunately
- masterofmisc 5y agoOhh i see. Yes, that makes sense. Thanks for taking the time to reply.
- ctvo 5y ago??? <DinnerPlate>{...map <Slicer><Apple /><Slicer/> }</DinnerPlate>
- extheat 5y agoThanks for the viz, haven't done React in a while so it's interesting to see how things have improved. The new paradigm seems alot better modularized and the logical structure seems easier to follow, combined with it taking advantage of newer JS features.
- tinganho 5y agoI think in the class world this is normally done by writing a service and injecting it on the constructor of the parent class. Since, React doesn't have DI built-in, it becomes problematic with the injection. hooks are essentially classes imo.
- arcosdev 5y agoHow does it become problematic? You just pass in dependencies as arguments to functions or components.