Live data from Hacker News

Frustrations with React Hooks

blog.logrocket.com

21–30 of 139 posts

Re: Frustrations with React Hooks

#21
Great post. I've also been ranty about hooks lately but am admittedly also just learning more ins/outs of things as I go.

That disclaimer aside, my biggest gripe is that I think hooks _could_ have been done in a "works from both OO and FP components" manner, so that all of these new (legitimately) "amazing to use b/c they're not HOC" APIs like the apollo hooks/etc. could be used by both types of components.

Instead, because hooks are they only non-terrible way of using libraries (again say apollo), users/codebases are basically forced to convert their OO components over to FP.

Specifically, to me the primary innovation of hooks is not "reinventing OO back into FP", it's "the ability for reusable code to attach itself to the component lifecycle".

I.e. a hook can know when componentDidMount/componentDidUpdate/etc. happened, and do the right thing. That's the primary innovation of hooks, IMO.

That would be extremely useful for OO components too, and also very doable, like just expose a component.addComponentDidMountCallback(...) type methods (or component.addEffect(...) or frankly even useEffect could do this b/c React implicitly know which component is being invoked right now).

With something like this, I think all of the "currently-FP-only" hook libraries could have "OO-based" equivalents, that are just as pleasant to use, and users could choose which paradigm they preferred on their own.

BUT, the biggest annoyance is that libraries would have to maintain both "FP hook" and "OO hook" versions, b/c current/FP-only hooks API didn't consider OO components a constituent in the design process.

(Specifically the only deal-breaker/breaking-API-change to use FP hooks from OO (if React wanted to allow this) AFAICT is that useState returns a tuple of [value, setter] instead of a State interface with getter/setter methods. If it returned a State getter/setter, then the useState could be invoked outside of the OO render() method, but then inside of render state.get() would return the current value. AFAICT all of the other hook APIs are already "OO-compatible".)

Re: Frustrations with React Hooks

#22

Earlier quoted context omitted.

I've completely stopped using class components after spending some time with Hooks in a small-to-mid-sized application. The big wins for me were: - passing an empty array as the last argument of useEffect makes useEffect work in a similar fashion to the old ComponentDidMount. You can have any number of useEffect invocations in a component, and for a component that is, say, loading data from two different sources, I f…

How do you handle the drawback that changing the context will rerender all components that use the context? Putting too much state into a single context does seem like it could cause performance issues, especially with state that changes often.

I'd identify which states change often and group them into their own context(s).

Re: Frustrations with React Hooks

#23

Earlier quoted context omitted.

I've completely stopped using class components after spending some time with Hooks in a small-to-mid-sized application. The big wins for me were: - passing an empty array as the last argument of useEffect makes useEffect work in a similar fashion to the old ComponentDidMount. You can have any number of useEffect invocations in a component, and for a component that is, say, loading data from two different sources, I f…

Can you elaborate a bit about Context? I've been curious but wrapping multiple context layers to get multiple values feels awkward and wrapping an object to get CD around that feels like it screws over React rerendering logic.

Sure. The app I'd been working on had previously been using the original 'render prop' style of accessing context in functional components and using the this.contextType accessor for class-based components. Both approaches had their downsides:

- 'render props' are fairly awkward to write, and add a lot of noise to a component that's working with data from multiple contexts.

- this.contextType can only give a component access to one context. This is a pretty big problem.

With Hooks, useContext lets you reference and destructure contexts in a really elegant way. Say you want to show a user's name if they're logged in, with the render prop approach it's something like:

  
    {({ isLoggedIn } => {
      return ( {isLoggedIn && i'm logged in} )
    })}
  
with useContext, you can do

  const { isLoggedIn } = useContext(AuthContext);
and then use

  {isLoggedIn && ...} 
to condtionally render anywhere in the body of your component without all the Context.Consumer business.

Re: Frustrations with React Hooks

#24
post #21

Great post. I've also been ranty about hooks lately but am admittedly also just learning more ins/outs of things as I go. That disclaimer aside, my biggest gripe is that I think hooks _could_ have been done in a "works from both OO and FP components" manner, so that all of these new (legitimately) "amazing to use b/c they're not HOC" APIs like the apollo hooks/etc. could be used by both types of components. Instead,…

I view the draw away from OO as a feature and not a bug. Classical OO patterns should have never been introduced into JavaScript, and it had a just fine object model, that no one ever took the time to understand properly, for those small use cases it was called for. Emphasizing the functional aspects of JavaScript, it's clear strength, is the right call.

It just seemed like it was thrown in there because Java and C# developers who were increasingly being forced to use JavaScript begrudgingly just couldn't live without their "class" keywords, so they took to the forums to make JavaScript more like a "real" language.

Re: Frustrations with React Hooks

#25
post #21

Great post. I've also been ranty about hooks lately but am admittedly also just learning more ins/outs of things as I go. That disclaimer aside, my biggest gripe is that I think hooks _could_ have been done in a "works from both OO and FP components" manner, so that all of these new (legitimately) "amazing to use b/c they're not HOC" APIs like the apollo hooks/etc. could be used by both types of components. Instead,…

> Instead, because hooks are they only non-terrible way of using libraries (again say apollo), users/codebases are basically forced to convert their OO components over to FP.

I know what you mean, but in practice it’s easy to retrofit a hook into a legacy class component by wrapping the hook in a tiny functional component. Sure, you have to find some other mechanism (e.g. make it a HOC, or use render props, etc) to make that wrapper component compose nicely with your class component, but that’s the price of not porting the whole thing over to hooks.

Re: Frustrations with React Hooks

#26
We’ve writing most new code with hooks (including the Apollo GraphQL hooks like useQuery and useMutation). Generally been really pleased with them but did get bitten hard the other day.

The value returned from useState is just a plain ol’ variable like any other so it also gets captured by closures like any another variable. We had an editor that updated some state and then an event handler (defined as a closure) that did something with the state variable. The state was updated as expected but when the event fired, the closure had the original value. It can be worked around via a container/useRef (and is maybe a code smell in the first place) but it made for some painful debugging.

Re: Frustrations with React Hooks

#27
post #21

Great post. I've also been ranty about hooks lately but am admittedly also just learning more ins/outs of things as I go. That disclaimer aside, my biggest gripe is that I think hooks _could_ have been done in a "works from both OO and FP components" manner, so that all of these new (legitimately) "amazing to use b/c they're not HOC" APIs like the apollo hooks/etc. could be used by both types of components. Instead,…

I view the draw away from OO as a feature and not a bug. Classical OO patterns should have never been introduced into JavaScript, and it had a just fine object model, that no one ever took the time to understand properly, for those small use cases it was called for. Emphasizing the functional aspects of JavaScript, it's clear strength, is the right call. It just seemed like it was thrown in there because Java and C#…

> it had a just fine object model, that no one ever took the time to understand properly

Plenty of the people who dislike Javascript's prototypal inheritance model and (relatedly) scoping rules do understand them.

Re: Frustrations with React Hooks

#28

One major point of the author is complaining that the dependency array in an effect is only compared by reference for objects and arrays. To me this is a feature rather than a shortcomming: I use immutable data structures all the time (with array and object spread operators it is really easy to do so) and the effect will only update when it really needs to - thus only triggering a re-render (or rather reconciliation)…

The example in the article can be fixed very easily and doesn't require immutable data structures. If you're fetching something from a url and you don't want to fetch twice from the same url, make the dependency the url itself.

Re: Frustrations with React Hooks

#29
post #27

Earlier quoted context omitted.

I view the draw away from OO as a feature and not a bug. Classical OO patterns should have never been introduced into JavaScript, and it had a just fine object model, that no one ever took the time to understand properly, for those small use cases it was called for. Emphasizing the functional aspects of JavaScript, it's clear strength, is the right call. It just seemed like it was thrown in there because Java and C#…

> it had a just fine object model, that no one ever took the time to understand properly Plenty of the people who dislike Javascript's prototypal inheritance model and (relatedly) scoping rules do understand them.

[deleted]

Re: Frustrations with React Hooks

#30
Overall I think React hooks are an improvement. My codebase is usually shorter and there is a lot less typing involved.

But hooks creates abstractions the developer needs to deal with that never existed before.

Hooks are not functional because they break referential transparency of functions.

You have to track dependencies manually and hooks are more difficult than they need to be for the "componentDidMount" equivalent. If you don't get the dependencies just right you end up with things not firing or in infinite loops.

You have to wrap your functions in "useCallback" or "useRef" just so the reference doesn't change and cause infinite loops.

You can't create abstractions where a hook calls another hook. So you end up having to inline a bunch more code into your function rather than outsourcing it into a helper function.

The positional order seems like it would be easy to work around if they allowed you to pass in a key. Not sure why that isn't available.

Post reply on HN