Live data from Hacker News

Common mistakes writing React components with hooks

lorenzweiss.de

81–90 of 98 posts

Re: Common mistakes writing React components with hooks

#81

Earlier quoted context omitted.

I haven't use hooks and don't prefer it, however I must say that there isn't alternative to hooks that is shorter in syntax, and maybe easier.

Yeah I wasn't sold on hooks at first, mainly because I was having to re-think stuff that I already knew, but man now I'm used to them I'm so much more productive and I absolutely love it

I echo this statement. I use Django a lot for my backends and I was very, very against moving to class-based views. I'm not sure why, I love OOP, but I was so used to function-based views. I finally made the switch (well, I use both when appropriate) and I love them.

During this time, I started playing around with React and I thought, I learned my lesson, it's class-based components all the way. Yet again, the community started going to "other" way with function-based components and I was steadfast in my attachment to classes - refusing to budge.

Of course, I eventually made the switch and wish I had done so sooner. Once you get the hang of hooks, they're so much easier to reason about and, as you said, make me much more productive.

Re: Common mistakes writing React components with hooks

#83
There are a couple of potential bugs in the useEffect one.

Firstly, the two examples aren't semantically equivalent. onSuccess can change between renders, so in the "wrong" version, the version of onSuccess that'll be executed is the latest one. Whilst in the "correct" version, it'll be the one defined during the render which was in play during the initial render.

If you always want to make use of the latest onSuccess in the "correct" version, you'll probably want to look into putting it on a ref.

Another issue with the "wrong" version is that onSuccess will be called a second time if its identity changes after it's already been called once, which is quite likely if its parent re-renders and doesn't make use of useCallback.

Ultimately I think the "correct" version is indeed better, but the question of which is the correct onSuccess handler is one that always needs to be seriously considered.

Re: Common mistakes writing React components with hooks

#84
post #70

The first one just feels like a premature optimization. Yes calling setCount forces a rerender of that component, but unless there's lots of subcomponents inside that component, I wouldn't bother. Chances are later you'll need that state in the view, and if you have "unexpected side effects" from rerendering then that is the problem. The other tips are fine; effects should have a single responsibility and links and b…

I have a really large chat app with thousands of users and I realized the other day that I accidentally re-render the root component on _every keystroke_. Still, it's not a disaster and I haven't bothered to fix it because no-one notices.

Shouldn't be a big deal if it's properly split into subcomponents and their props don't change with every rerender as well.

Re: Common mistakes writing React components with hooks

#85
post #49

Earlier quoted context omitted.

To me, the killer feature of React is how easy it is to mix with standard "vanilla" JS libraries. The "React" version of a library is usually a fairly trivial wrapper around the "normal" version. In contrast, integrating with Angular is a lot more involved and is in effect its own ecosystem. The other thing I can't stand about Angular is that it puts its proprietary templating language "in control" of components. Whi…

Can you provide some examples? My experience is that almost any library you end up using is built specifically for React and not vanilla.

Compare https://github.com/nhagen/react-intercom/blob/master/src/ind...

with https://github.com/PatrickJS/angular-intercom/blob/master/an...

And that's the small one. There's also https://github.com/CaliStyle/ng-intercom

As another example, consider HTTP. Angular provides its own special HTTP class. With React I just use the standard Fetch API.

Re: Common mistakes writing React components with hooks

#86

Earlier quoted context omitted.

If you need an effect to run before the component draws, try `useLayoutEffect` instead of `useEffect`. https://reactjs.org/docs/hooks-reference.html#uselayouteffec...

How do you handle a useEffect that relies on state, but you don't want it to run on first render? I usually have a separate state that is "firstLoad" and toggle that in the effect and exit out, then its free to run on successive invocations. But typing this out - it makes me the think the dependent state itself should be driving if it runs or not...

I don't think there's a way around tracking that `firstLoad` value. A `ref` is probably a better choice than a separate state value because you don't need to render when the component becomes aware that you're past the first render. You could do it in a simple hook:

  function useFirstRenderComplete() {
    const renderCountRef = useRef(0);

    useEffect(() => {
      if (renderCountRef.current) {
        return;
      }

      renderCountRef.current += 1;
    }, []);

    return renderCountRef.current !== 0;
  }

Re: Common mistakes writing React components with hooks

#87
post #50

The first one just feels like a premature optimization. Yes calling setCount forces a rerender of that component, but unless there's lots of subcomponents inside that component, I wouldn't bother. Chances are later you'll need that state in the view, and if you have "unexpected side effects" from rerendering then that is the problem. The other tips are fine; effects should have a single responsibility and links and b…

Yes. The author should replace "This is dangerous" with "This is a tiny bit sub-optimal" in the first example. EDIT: "This is dangerous" is also the wrong label for the 2nd example. Should be "This is not the cleanest way" EDIT2: "This is dangerous" is also the wrong label for the 3rd example. Should be "This is not the most readable". I'd also note that I'm surprised the author has seen this mistake a lot; the "solu…

Well, example 2 is legitimately dangerous if your app is required to be accessible.

Re: Common mistakes writing React components with hooks

#88
post #40

A recent thing which has been rubbing me the wrong way in React has been the exhaustive dependencies for useEffect and other hooks. Sure, in the case someone would alter say the function provided as props it should be included in the dependency array. Yet in most cases, such as the example #3 in the article, this would not happen (or be even desired). Rather, if it did it would be a bug and an appropriate error would…

I mean, onSuccess could change. And as you suggested, creating the extra callback is redundant. const fetchData = () => { setLoading(true); callApi() .then((fetchedData) => { setData(fetchedData); onSuccess(); }) .catch((err) => setError(err)) .finally(() => setLoading(false)); }; useEffect(() => { fetchData(); }, []); becomes useEffect(() => { setLoading(true); callApi() .then((fetchedData) => { setData(fetchedData)…

Sure it could but if the intention of the developer is to run the API call only once per mount, never otherwise, it would be more appropriate to throw an error instead of just adding pointless dependencies. It just seems like a dumb overhead which goes against the actual goals of the developer.

Re: Common mistakes writing React components with hooks

#89
post #71
post #40

A recent thing which has been rubbing me the wrong way in React has been the exhaustive dependencies for useEffect and other hooks. Sure, in the case someone would alter say the function provided as props it should be included in the dependency array. Yet in most cases, such as the example #3 in the article, this would not happen (or be even desired). Rather, if it did it would be a bug and an appropriate error would…

There is no harm in adding something to the dependency array that you don't expect to ever change. The linter is your friend; make its job easier.

Well, I disagree. As I said in my other reply - if the intention is that the prop is immutable there should be an error instead of very strange recomputation of the useEffect hook.

Re: Common mistakes writing React components with hooks

#90
post #75
post #4

Nitpick, but React is not a framework, it's a library. People miss this point often eg when they compare React to Angular

React's documentation calls it a library but we don't have to. I think the reason people go back and forth on this is that there are a couple definitions of framework out there. A lot of people consider it to be a sort of continuum, where a library becomes framework-like as it adds more and more functionality. I understand that framework can sometimes connote bloat, which is probably why the React docs avoid the term…

React _is_ a framework, because:

- You hand it your code and it calls your code when it wants to

- Your code must conform to React's expectations.

React is _not_ a framework, because:

- It only focuses on one thing: defining a tree of UI components. It doesn't include anything for HTTP requests, module definitions, generating expected file structures, or any of the other stuff you'd see in Angular and Ember.

- You are responsible for initializing React in your app, and you can use it in a range of situations, from a full-bore SPA to adding some interactive widgets to an existing page.

All those are true simultaneously.

Post reply on HN