5 ms·
Maybe I am crazy or old school but I though the concept of creating component as a class with standard functions to override (and defining a contract with props
by mharroun 8y ago
Maybe I am crazy or old school but I though the concept of creating component as a class with standard functions to override (and defining a contract with props types) took a unwieldy language like JS and gave a sane and standard approach to it.
I now look at more "modern" functional components /w hooks and find it VERY hard to understand the data a component takes and how it uses/responses to interactions.
It feels like react was class based... and now that functional coding is the "in thing" its trying to shoehorn everything into functional components. In the end it really turns me off to functional programming as I see many developers sacrificing readable/understandable components to save a few lines of code.
- vmware505 8y agoI have the same feeling. I would prefer to use classes rather than functions. More natural and nicely work with Typescript. Luckily React is only a library and it is up to you how do you use it. I got used to working with classes and objects. For bigger and serious project I prefer Ember.js, which is modern and easy to pick up (https://yoember.com https://yoember.com), but for some tiny project React is also a good choice with Typescript. I guess hooks is a good option for devs who prefer functional programming.
- underwater 8y agoClasses aren't really that great in React. You typically need do a lot of juggling to co-ordinate lifecycle hooks. Trying to do something like register, update and unregister a listener feels very verbose with classes because you don't truely control the instance lifecycle – React does.
- WorldMaker 8y agoHooks work just fine in Typescript. Not just because Typescript already does will with Functional Programming, but because the types of most hook functions are generally rather simple. `declare function useState<T>(startState: T): [T, (nextState: T) => void]` is pretty simple function signature and most cases Typescript picks up (infers) that T generic parameter for you based on startState. Almost every other Hook function has a similarly simple type signature, despite the complicated "guts" of how React keeps track of hooks internally. (Which also doesn't seem all that complicated, relatively speaking.) (I still want a way to represent the order of effects / no effects in control flows rules in Typescript's type system, but linters will handle it fine. At this point it's mostly just a personal toy project/curiosity because Typescript feels like it has enough of the basic building blocks in the type system such as `never` to get quite close.)
- Waterluvian 8y agoSame. React passed the, "this is obvious and it's clear where it fits into the real world" test for me years ago with class based components. But these new features aren't passing that test at all. I struggle to grok what hooks do that I was missing before. It gets me wondering if the React team is in a position to know when React is good enough and needs to be left alone for the most part. The good news is that I seem to be able to just ignore hooks and remain very productive. I even started ignoring advice on when to use an SFC instead of a class and found myself happier and more productive with better code.
- danabramov 8y ago>I struggle to grok what hooks do that I was missing before. I wrote about this too: https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889 https://medium.com/@dan_abramov/making-sense-of-react-hooks-... Hope it helps. As another commenter note, the OP article discusses the pathological case. An API can make a hundred cases simpler but discussions will always focus on the few ones that got harder. The point of this post is to show how to work through this case and why the _end result_ is more flexible and powerful than before.
- Waterluvian 8y agoThanks. Generally speaking my mindset is that the benefits will become clear in time, or they will be leveraged by others and invisible to my everyday use. But my final point still stands: the win with how React is evolving is that I can completely ignore these new features for a short/long/infinite amount of time and not be in trouble.
- tokyodude 8y agoAgreed. The "everything needs to be a react component" is bad IMO. My example, I'm making an image viewer. I want a context menu. IMO the ideal solution some generic right-click (context menu) function/handler. you attach it to each image. On right click the image is passed to the handler and the handler does something with it. That's relatively low overhead. There's no per image data. But the React stuff I found made a context menu of nested components per image. Effectively <image><contextmenu><menuitem/><menuitem/><menuitem/><menuitem/><menuitem/></contextmenu></image>. For 1000 images that's 6 thousand components created, 6000 things added to the virtual dom to be diffed, 11000 considering the content of each menuitem is actually yet another dom node. There's tons of react libraries like that where they try to shovel every concept into a component.
- mifreewil 8y ago> IMO the ideal solution some generic right-click (context menu) function/handler. you attach it to each image Ideally, you would only have a single event listener that handles events for all images.
- frosted-flakes 8y agoWith React, it's one and the same thing. React has a single event listener at the top level, then creates synthetic events that it passes down the tree. You can still do native event listeners, but there's no reason to, except for listening for events on `window`, etc.
- mifreewil 8y agoThis just sounds like inexperienced programmers. I've played around with React and it doesn't seem like there is anything special about React that would prevent you from creating a single instance of a component and have it's state update based on what image you are right-clicking on.
- scrollaway 8y agoIn your example, the contextmenu component should not be created until the image is right-clicked. So your <image> code would look something like this: return (<><img .../> {contextMenuActive ? <contextmenu>...</contextmenu> : null}</>);
- mambodog 8y agoHooks address a very specific problem with classes: composability. You can use the various builtin hooks to do stuff that (in class-based React) previously required implementing methods (eg. componentDidUpdate). Using those methods works fine until you want to split out and reuse part of those methods in other components. You can certainly try class composition: creating little classes that you call in each of the relevant lifecycle methods. However this adds a lot of boilerplate to components which use the composed objects (as is common with class composition). It's also awkward to share the setState API with these composed classes. The Custom Hooks approach[1] with React Hooks just makes it really easy to use state and lifecycle functionality when extracting common behaviour to can be shared between multiple components. React has tried to address this composition issue several times in the past, and I think hooks are the nicest yet: React's old 'Mixins' feature got a lot of the way there, but still didn't compose perfectly. For example, you had to avoid method and state key name collisions between mixins. Creating a 'Higher Order Component' is another approach, which is less verbose than class composition, but makes your component tree deeper, and can also be annoying to statically type. The community also came up with 'Render Props' to address much the same issue. And of course, you can always just continue to use classes if you aren't experiencing any of these pain points. Hooks just compose quite nicely in cases where none of these other approaches do. [1]: https://reactjs.org/docs/hooks-custom.html https://reactjs.org/docs/hooks-custom.html
- goatlover 8y agoIs all this because inheritance is discouraged? Seems weird to got to that much trouble to avoid a builtin language feature that does the thing you want, which is reuse methods across components.
- mambodog 8y agoHow do you compose two base classes into a subclass? That's basically what hooks allows. You can use two different, unrelated custom hooks in one component, and a different combination in another component, without having to bundle them into base classes.
- deleted 8y ago[deleted]
- underwater 8y agoReact didn't even start out with classes — React.createClass came first. It allowed you to define lifecycle hooks for a component, but wasn't supposed to be a generic class implementation.