5 ms·
The class-based examples given are a bit disingenuous. Not only the author is not using anything like redux, the class examples look deliberately made longer t
by chmln 7y ago
The class-based examples given are a bit disingenuous.
Not only the author is not using anything like redux, the class examples look deliberately made longer than they should be. For example, one of them has 4 setState() calls after each other instead of combining them. Another manually performs deep equality checks for each key instead of using some library/helper.
The conciseness of React hooks also relies on the knowledge of implicit ordering of when certain functions are called, while lifecycle hooks are obvious and straightforward. Optimizing for writability is not the best approach for anything beyond prototype-level codebases.
- epidemian 7y agoI don't think the class-based examples look deliberately inflated. > or example, one of them has 4 setState() calls after each other instead of combining them. You would still need one line for each state property set: this.setState({ data: newData, dimensions: getDimensions(), xScale: getXScale(), yScale: getYScale(), }) (Unless you were to compress all of that into one line...) In fact that makes things longer in terms of LoC. A bit less noisy though, that'd be true. > Another manually performs deep equality checks for each key instead of using some library/helper. Yeah well, I think this is completely fair if you want to "compare oranges with oranges". If the author were to include external libraries, then they would no longer be comparing "Reach with hooks" with "classic React", but with "classic React + some X library" instead.
- mharroun 7y agoWhy not put the function calls into the render? And only decide to rerender on state change. You could push nearly all that logic back into extends Purecomponent
- Klathmon 7y agoThey point out that the get* functions are supposed to be "computationally expensive", and you don't want something like that in your render method. But also in either the current or near future versions of react, with Suspense and concurrent rendering, the render method may be called multiple times over the course of a single render. So if any of those functions aren't entirely pure, there is a good chance there will be bugs from that.
- vmind 7y agoI don't think it's fair to say React hooks are optimising for writability, even if they are much shorter, but modularity. While lifecycle methods are 'obvious and straightforward', they often spread related functionality across multiple different functions, which can be more easily grouped together with hooks. And if you have similar lifecycle-based functionality that needs to be shared between multiple components, you end up with a variety of not-great solutions, whereas that is simple with hooks. That's not to say hooks aren't without a downside, it is more to learn, with a different mental model, and their own edge cases. But having used hooks exclusively for a larger project, I couldn't imagine going back to lifecycle methods.
- judofyr 7y agoAll of these discussions seems to forget that React hooks is two different things combined: (1) it's a new magic way of having stateful components and (2) it's a new set of APIs. I don't quite see why they _have_ to be so coupled. Wouldn't this be possible as well? class Chart extends Component { constructor(props) { super(props) this.useEffect(() => { const newData = getDataWithinRange(dateRange) this.setState({data: newData}) }, () => this.props.dateRange); } } You're not able to completely mirror the API (e.g. here the dependencies has to be a function), but you would get code which behaves very similar without the weird hook API. I'm sure these APIs would have various gotchas in order to be used correct, but it's not like React hooks is gotcha-free at all. Interestingly, useMemo doesn't even need to be defined in React in a class-based component: function useMemo(f, dep) { let prev; let value; return function() { let next = dep(); if (next !== prev) { prev = next; value = f(); } return value; } } class Chart extends Component { data = useMemo( () => getDataWithinRange(this.props.dateRange), () => this.props.dateRange) ) } This is also just one of the possible APIs. I'm sure there are variants of this which are more performant and/or easier to work with.
- acemarke 7y agoWould it be _possible_ to implement hooks as part of classes? Sure, it's just software, code can implement basically anything. But, the React team deliberately opted to only implement hooks for function components for a few reasons: - Function components didn't have capability parity with class components in terms of having state and side effects - Class components already had the ability to do this kind of functionality overall - Long-term, function components are easier for React to deal with for things like hot reloading and the upcoming Concurrent Mode. By dangling a carrot to convince folks to move to function components + hooks, it becomes easier to implement that functionality for the React team.
- deleted 7y ago[deleted]
- gatherhunterer 7y agoRedux adds complexity as well, but I agree that the code looks to be much more repetitive than is necessary. I have never seen multiple calls to setState put one after another like that and it does seem disingenuous to make it look like people write React class components that way.
- acemarke 7y agoI've seen a _lot_ of folks put multiple separate `setState` calls in a row, one for each field they want to update. I make sure to point out that it's nicer to read if they're collapsed into a single call, but it's a very common thing.
- gatherhunterer 7y agoA scrum master or maintainer needs to proofread and prevent this. That is is the purpose of code review. It’s too bad that repetition does not stand out as a mistake to so many with whom you have worked.
- acemarke 7y agoThat's literally my point. Folks learning React will do that at first, because they don't know better. We _have_ caught that in code reviews, taught them not to do that, and moved on. But yes, it is an actual thing I have seen people (coworkers and otherwise) do, not some made-up problem.
- JMTQp8lwXL 7y agoA well structured argument should take the strongest interpretation of both sides. Having code quality/clarity on one side of the argument, while omitting it on the other, makes it more difficult to conclusively draw an informed opinion.