3 ms·
I think the old way is simpler in the sense of building on fewer concepts, and therefore allowing an easier learning curve, if you grant that understanding the
by dkarl 7y ago
I think the old way is simpler in the sense of building on fewer concepts, and therefore allowing an easier learning curve, if you grant that understanding the React component lifecycle is required and inevitable. Once you understand the lifecycle, running code when certain lifecycle events happen is a very small, concrete conceptual leap. Names like "componentDidMount" tie directly into your fundamental understanding of React. If using them to maintain state forces you to deepen your understanding of the component lifecycle, that effort will pay dividends when you have to debug, optimize, understand someone else's wacky code, etc.
Hooks, on the other hand, have to be learned as an additional and separate concept. In fact, each hook has to be learned. You won't have a clue what "useState" and "useEffect" do just by having a knowledge of React fundamentals. If using hooks allowed developers to avoid knowing the React component lifecycle, an argument could be made that they provide a simpler alternative, but I don't think anybody is going to get very far without being forced to learn about the component lifecycle. If someone were to say, "The React lifecycle is hard to understand, so use hooks instead," that would be a false promise. Hooks are something extra to learn, not an alternative to understanding the lifecycle. To the extent that a programmer can avoid understanding the lifecycle by using hooks instead, they are just putting off that learning curve until they have to traverse it later, probably under the pressure of debugging some nasty issue.
Hooks seem to win from another perspective, though, which is that by accepting the cost of adding this new concept to your mental model, you can write simpler-looking code that is easier to keep error-free. To me, that's the trade-off. Hooks are an extra complexity to understand, and each new hook can encapsulate arbitrary complexity and behavior that isn't obvious from reading code that uses them, but the code that uses them can be more concise and perhaps easier to read and keep correct.
- ratww 7y agoI think this also falls into the same familiarity trap as the parent. Let me preface this by saying that I think it's not necessary to conflate the "lifecycle methods" with the component lifecycle in itself, and I disagree with the premise that the methods are a fundamental concept of React. Of course, this is how people were historically taught, but it is entirely possible to conceptualise and understand the lifecycle of a React component without even knowing about lifecycle methods, just in terms of how useEffect works, for instance, and this is how a lot of people using hooks today think. It is entirely possible to understand how re-renderings are triggered and stuff like that without even knowing about class components and lifecycle methods. So, hooks might seem like an additional concept to people used to class components and lifecycle methods, but that's just because of familiarity. For people learning hooks first, the opposite is true just as well. IMO this paradigm shift in thinking is also essential for people used to class components that want to be more productive in codebases with mostly hooks. I haven't thought about componentDidUpdate and friends in months.
- pandler 7y ago> I think the old way is simpler in the sense of building on fewer concepts, and therefore allowing an easier learning curve I would disagree with that premise. From my own experience and from having mentored developers on class components (so like ~7 data points), I'd say it's far easier to reason about state flow with hooks than lifecycle methods. That's an important point, because I see far more bugs with incorrect or incomplete state flow than I see with component lifecycles. Hooks are simply easier to reason about. With hooks, you read the code top to bottom. Then, something changes either with the data or in response to user input, and then you read the code top to bottom again with that new state. The only learning curve there is to understanding the basic premise of hooks is that "if this value is different from the last time you read the code top-to-bottom, then re-read/execute this code block" > If using hooks allowed developers to avoid knowing the React component lifecycle, an argument could be made that they provide a simpler alternative, but I don't think anybody is going to get very far without being forced to learn about the component lifecycle. If someone were to say, "The React lifecycle is hard to understand, so use hooks instead," that would be a false promise. That is exactly my premise, and I don't think it's a false one. Since moving to hooks, I can't remember the last time I had to care about the React lifecycle. Again, the mental model is "Read the code top to bottom; something changes; read the code from top to bottom" ad infinitum. Yes there are situations where class components provide more intimate control (componentWillUnmount comes to mind since I'm not aware of a hook for that), but are we really optimizing the majority of our code for exceptional cases? Another data point: I haven't seen functional components turn into a complete mess from inattentive developers in the same way I've seen class components turn into indecipherable setState tangled messes. The only time I've experienced the pressure of sifting through component lifecycles under the pressure of debugging a time-sensitive production isssue is because I was using component lifecycles in the first place. It's a moot point.
- cmwelsh 7y ago> Yes there are situations where class components provide more intimate control (componentWillUnmount comes to mind since I'm not aware of a hook for that), but are we really optimizing the majority of our code for exceptional cases? The return value of invoking React.useEffect’s first parameter is a cleanup function which serves this purpose. Everyone in this thread is ragging on core concepts like useMemo or useEffect. Once you know these core functions, you’ve learned all the magic. Then you can write spells of your own.