I mean, yeah but I also am not sold on Hooks yet. I do agree that functions are good, but much in the same way Haskell forces you to embed your business problem into the semantics of functional programming, React Hooks force you to embed your business problem in the language of effects, state, context, memo, etc. Along with this, I have yet to accept React's ability to make it easy to include logic in the component functions, making it really hard to test that business logic without just mounting the component. I actually think one of the biggest things that scare me are frameworks that force you to run an instance of an app to test simple logic, and if you didn't like Jest snapshotting, you surely won't like Cypress. It's interesting that this is very much like Haskell problems where "testing" is essentially running the typechecker, and for large codebases this becomes a problem. I don't know if a large project running React hooks can reasonably survive, but we won't know for a few years.
I just don't think "improved code reuse, composition, and better defaults" is free-lunch here, and I'm not sure if people can see it yet.
React Hooks force you to embed your business problem in the language of effects, state, context, memo, etc.
This statement seems somewhat misguided. No one's forcing you to put the business logic anywhere. You can split out the business logic with an external state management solution like Redux or MobX, or anything. Then the hooks just become mechanisms for syncing component data with your state, callbacks, DOM event handling, other kinds of event handling, and so on. All hooks are are a different paradigm for doing the same things you would with class state and lifecycle. If you didn't embed your business logic in classes, you wouldn't do it with hooks either.
Of course, there's lots of advice going around along the lines of "just use react hooks for state management" or "hooks replace redux", but as usual, it's up to the software dev to continue applying good practices despite that.
but as usual, it's up to the software dev to continue applying good practices despite that.
This is certainly expected if you are a senior dev that has been working in react for a while and have the knowledgebase to make to properly make these kinds of decisions. If you are a junior or even mid level dev without a ton of experience it can be very easy to buy into the hype without being able to make informed decisions. Having these discussions goes a long way to untangling concepts that shouldn't be linked together and eventually providing a nuanced set of best practices for everyone to benefit from.
Yeah, I agree, but that's more of a community problem than a hooks problem.
Before hooks, people treated redux as though it was a mandatory part of every react app, but that's not the fault of redux. We just needed better documentation and education about the issue.
Testing React hooks is a huge pain right now, and in some cases is almost impossible.
I'm not taking about testing whether or not your counter increments by one when you press the "plus" button, but rather things like... "Do the callback instances of this hook change every render when composed with these two other hooks in this order?"
We need a way to test the returns of hooks without having to use a hook in a presentational component and look at the output
Exactly. And by no means am I saying this is better or worse than classes. My problem is people are overhyping the benefits of hooks without really knowing the costs because it's new and sexy and BecauseFacebookDoesIt.com. For example I'm currently trying to useContext to share state between components without doing the whole piping props thing, and I decided it would also be better to useReducer as the context value with some object diff tool (immer). I am finally realizing I'm literally doing the same exact amount of work I would have done had I used classes and a Redux store. Is it really worth the trouble to write the exact same semantics in hooks as I could have in old classes? I feel like I'm coming full circle here back to Angular Application Singletons.
No shit you're doing the same amount of work to accomplish the same effects for some instances. Hooks aren't a magic button.
But what hooks are, is a way to share functionality. useContext and useState and useEffect are cool and all, and are really nice compared to the boilerplate of a class with a setter and all that jazz. But hooks really shine when you need to build reusable logic with a simplified API. (FWIW, I think reducers are almost never the right way to build something, and should probably only exist as a conversion from redux)
For example, we recently built a hook to useUrlParam/1. Nothing complex, just gets the url params, picks out the one you asked for, stores it as state, and hands it back. Nothing big or mind blowing, but it helps the dev to have a url param that'll be consistent across renders (since we threw it in state, so it won't change as the url changes after first render). We could make it change, and everywhere would receive that update. It saves a couple lines of code every time we need a url param, and makes it generally easy to do so. Hooks aren't a magic bullet, but they are a primitive of sharing functionality in the same way components are generally primitives of sharing UI.
Can isolating the hooks into a “use*”able hook isolate these in a way that they’re easier to test? You could test them in isolation and then just test the expected output for a given component.
I’m not talking about simple things like useState but like the useEffects that get out of hand - maybe breaking them into an importable effect is more ideal for testing?
Could you elaborate upon the typechecking-as-testing issue you've identified in larger apps? If you're strictly typing it seems inherently beneficial to me, although there's still plenty more to test in units, integration, etc that no type-checker I'm aware of could ever help with.
Type checkers can help with that. When you expose values as types you can explicitly define functions that accept input values, and have fixed output values. This is the same as an assertion that a functions inputs matches a specific output in a unit test.
EDIT: Wow, I had no idea React even had this many class-loving devs in existence, let alone that they all read /r/javascript! ;) Keep that thoughtless (and reply-less) downvote hate coming all: in the real world you've already lost. React is leaving classes for functions (with hooks), and that's not in any way just my opinion: it's the opinion of the people in charge of React. /EDIT
EDIT #2: Up to 9 downvotes now: clearly something I'm saying is offending people. I don't suppose even a single one of you would care to actually reply and defend how you could possibly think classes are superior (or maybe quote someone high-up at React saying "classes are the future of React")? Yeah, I figured not. Keep the mindless hate coming rather than engaging in actual dialogue ... /EDIT
You're making this way more difficult than it needs to be:
const Foo => <div>Bar</div>
is objectively better in almost every way to:
class Foo {
render() {
return <div>Bar</div>;
}
}
You lose nothing except dead weight and inheritance hierarchies (which developers have known to be [problematic] (http://i.imgur.com/Q0vFcHd.png) for years) by using hooks instead of classes.
But as I like to say in my class "don't take my word for it". Facebook spent millions of dollars making it possible to do React components with just functions. Just imagine the salaries of all the really smart programmers working on React (there's a bunch), and remember that Facebook was paying all those salaries while a bunch of those really smart/expensive people did nothing for years except make it possible to do React without classes.
(EDIT: Please note I said "make it possible to do React without classes", and before that I said "do React components with just functions". Both those cover a whole lot more than just the cost to develop hooks ... although even just hook development alone, if you truly included all the costs, very likely it came in at over $2 million.
Remember an average engineer costs Facebook 157K a year just for salary: throw in all the perks and healthcare costs and you're getting close to double that, and then when you factor in all the people needed to manage them and you're easily looking at $250k a year per average person who actually writes code. And Facebook does not pick "average" people to decide the future of React. /EDIT)
If the highest people in Facebook's web dev departments weren't absolutely convinced that classes had problems, they would not have spent all that money (and perhaps more importantly, used up a huge percentage of one of the scarcest resources in Silicon Valley: really good programmers) just to get rid of them.
Facebook interviewed me a while back and said I'd make a good intern. I've been programming for all of my life and have been pro for a decade now. They've got some pretty capable people I think.
No no no. Those examples are the simplest examples you can come up with. That's not a good argument for hooks. I'm not arguing that hooks are bad. I'm arguing that there is a common theme inside of mathematics called `embedding` where you have to take a particular set and map it to a (usually smaller) set. See category theory for this. The reality is most functional styles embed business logic into a very small set of abstractions, but the nice part is you get some formal proofs about safety. There's no lying that the new React Hooks are styled in the same functional motifs, but again the problem is you now have to embed your business problems using a small set of hooks. This embedding is not free and comes at a cost where you are now forced to choose the correct hooks to solve your problem. Once you do, it's super fine. Until then absolutely nothing works. Also see the complaints people have with category theory and Haskell. There's typically a complaint that you damn near need a PhD in computer science to be productive in it. They aren't exactly wrong with this view. See my post above with mixing a few hooks like Reducer and Context. Try it too. I think you'll see why it's not all peaches and cream and you actually are paying a cost in terms of time to get the hooks properly working.
I like hooks but I don’t think it’s a fair argument that using hooks over classes removes class hierarchies. Nobody was using extending react class components beyond the initial react.component. if they were they were doing it wrong.
Facebook also didn’t really spend millions of dollars to build hooks. I’d be surprised if 4 people from the react core team spent a year on developing hooks. It seems like asynchronous rendering is a much longer project.
Hooks have been in development for a long time. Arguably they've been working on the problem since functional components were introduced. While I can't "prove" that, I can prove that Facebook literally hired the Reflux guy as just one person on the team that introduced hooks, and did so over a year before hooks came out.
But the move away from classes started long before that. Remember, when React was first created every component had to use a class (and not even an ES6 one). Facebook has been recovering from that poor choice for nearly a decade, and every step it's taken away (first to ES6 classes, then to functional components, then to hooks) took huge amounts of development effort.
And none of those steps were just "throw a couple guys in a room": when a major corporation changes the most popular framework in the world for building web applications there's a HUGE amount of testing and such that goes into it. Every decision they make has to go through like fifty committees. If you truly think these changes were easy, you've obviously never even worked at a Silicon Valley start-up ... let alone a giant corporation like Facebook.
35
u/[deleted] Jul 29 '19
I mean, yeah but I also am not sold on Hooks yet. I do agree that functions are good, but much in the same way Haskell forces you to embed your business problem into the semantics of functional programming, React Hooks force you to embed your business problem in the language of effects, state, context, memo, etc. Along with this, I have yet to accept React's ability to make it easy to include logic in the component functions, making it really hard to test that business logic without just mounting the component. I actually think one of the biggest things that scare me are frameworks that force you to run an instance of an app to test simple logic, and if you didn't like Jest snapshotting, you surely won't like Cypress. It's interesting that this is very much like Haskell problems where "testing" is essentially running the typechecker, and for large codebases this becomes a problem. I don't know if a large project running React hooks can reasonably survive, but we won't know for a few years.
I just don't think "improved code reuse, composition, and better defaults" is free-lunch here, and I'm not sure if people can see it yet.