[HN Gopher] Understanding UseMemo and UseCallback
       ___________________________________________________________________
        
       Understanding UseMemo and UseCallback
        
       Author : feross
       Score  : 60 points
       Date   : 2022-08-30 17:02 UTC (5 hours ago)
        
 (HTM) web link (www.joshwcomeau.com)
 (TXT) w3m dump (www.joshwcomeau.com)
        
       | moltar wrote:
       | Really nice, but works badly on mobile with a small screen.
        
       | continuational wrote:
       | Once you add useMemo and useCallback, your code will become
       | pretty unsightly though. I wish React had a better solution to
       | this problem.
        
         | gedy wrote:
         | Agreed, many libraries and frameworks have built in support and
         | simpler syntax for computed values, like MobX, or even older
         | frameworks Ractive or Knockout. React takes a very "code-y"
         | approach to this, which I guess some people like.
        
         | brundolf wrote:
         | This talk suggests they're exploring ways to improve the DX:
         | https://youtu.be/lGEMwh32soc
        
         | harrisonjackson wrote:
         | You can largely avoid useMemo by keeping your props and state
         | in the format you actually need them.
         | 
         | The solution for more complex useMemo and useCallback usage is
         | to create your own hooks.
         | 
         | You can compose all the hooks into a single hook that your
         | component uses and return from that hook whatever your
         | component needs. This is common with components that have a lot
         | of event listeners that can trigger local state and/or redux
         | state changes.
         | 
         | We have a spreadsheet component and the individual cells had
         | some pretty gnarly hooks and after pulling them into their own
         | custom hook we've been able to maintain them nicely.
        
       | jefb wrote:
       | React's push towards a functional model with all the use* hooks
       | is so sad to watch.
       | 
       | A stateless programming model in a domain where state is so
       | fiercely coupled to program utility is inevitably going to spawn
       | this garbage.
       | 
       | Class based components with MobX managing state was, and still
       | is, a dream to write __and__ read.
        
         | jameshart wrote:
         | I wish people would stop saying this. Hooks aren't functional
         | or stateless.
         | 
         | Literally, calling 'useMemo' twice returns two different
         | objects, because the function keeps track in internal state of
         | how many times it has been called.
         | 
         | Hooks are very deeply _imperative_.
         | 
         | They are a way of obtaining some benefits that are easily
         | obtained in functional programming via higher-order functions,
         | but expressed in a way that makes them easily consumed in an
         | imperative code body.
        
           | eurasiantiger wrote:
           | That is all sorts of funny for people who remember
           | PureComponent and all the hype about functional components.
           | 
           | React has always been an exercise in smoke and mirrors.
        
           | jefb wrote:
           | Hooks are obviously not stateless - I'm saying they were an
           | inevitable consequence of the push towards functional
           | components and that they represent an inferior development
           | experience. No one needed to write 2000 words on how to use
           | setState.
        
       | telman17 wrote:
       | I love Josh's writeups. His CSS for JS devs course is also
       | fantastic for folks who want to get better at CSS.
        
       | babyshake wrote:
       | I completely understand why you would want to memoize values and
       | reasons to use useMemo. But I don't really understand why you
       | would want to memoize a function to avoid it being re-generated.
       | I guess maybe it saves a tiny performance hit, but does
       | useCallback result in significant performance improvements?
        
         | foob wrote:
         | If you're passing the callback as a prop to a child component,
         | then it will cause that component to be re-rendered every time
         | the parent component renders unless you memoize the callback.
         | This happens because React checks referential identity when
         | determining whether props have changed. The performance hit of
         | unnecessary re-renders can be fairly significant in large React
         | apps.
        
           | protonimitate wrote:
           | Memoizing the callback prop only matters if you wrap the
           | child component in "React.memo".
           | 
           | If you don't wrap the child component with "React.memo",
           | every time the parent renders the child will render
           | regardless of prop equality, even with memoized
           | props/callbacks.
        
           | fabian2k wrote:
           | React will rerender the child component anyway in this case
           | even with useCallback. Of course you can prevent this by
           | using React.Memo on the child component, and in this case
           | using useCallback makes it possible to optimize rerendering
           | by providing stable values for functions you pass to that
           | component.
           | 
           | Adding useCallback for functions only does something useful
           | if you also React.Memo those children. So while this is a
           | very important optimization, it's not one you need to apply
           | to everything.
        
         | [deleted]
        
         | brundolf wrote:
         | It actually doesn't _directly_ help performance at all, because
         | you 're still creating a new function each time; they just get
         | thrown away after the first time (until dependencies update)
         | 
         | It only exists/is done to give you a stable reference so you
         | can avoid triggering downstream dependencies (hook arrays and
         | React.memo'd components)
        
         | edgyquant wrote:
         | Is this not extremely useful for hook interfaces?
        
       | GenerocUsername wrote:
       | Nothing wrong with this blog but I'm pretty sure the exact title
       | has been done 1000x
        
         | lucasmullens wrote:
         | I Googled "Understanding UseMemo and UseCallback" and there
         | were 7 results, all referencing this exact article.
        
       | latchkey wrote:
       | His previous one on rerenders was fantastic... many lightbulb
       | moments.
       | 
       | https://www.joshwcomeau.com/react/why-react-re-renders/
       | 
       | FB should hire him to rewrite their docs.
        
         | andy_ppp wrote:
         | This is really excellent. I have a hook that is producing
         | updated data every second, it's pretty annoying that this
         | causes everything below where the hook was included to be re-
         | rendered each time, even if the updated data isn't included. I
         | can't help but think using redux and connecting components to a
         | global store as far down the hierarchy as possible was much
         | more efficient. Is there an alternative way to do this with
         | hooks to avoid re-rendering?
         | 
         | One thing I've started doing everywhere is putting a
         | logger.debug("rendering WidgetX") at the top of every component
         | to catch anything weird as I go along, it's been pretty
         | helpful.
        
           | encoderer wrote:
           | Push the hook down to the lower components, and use it like
           | you would redux?
        
       | cercatrova wrote:
       | I always enjoy Comeau's blog posts, they're the essence of
       | interactive learning. For real world things, I also like Bartosz
       | Ciechanowski's work [0], they have very highly detailed
       | renditions of things like mechanical watches and internal
       | combustion engines.
       | 
       | [0] https://ciechanow.ski/
        
       | johnny_reilly wrote:
       | I love the way this is put together. Just outstanding work -
       | totally readable with interactive illustrations. Hats off!
        
       | foomatic wrote:
       | So useMemo === Vue's computed values??
        
       | worble wrote:
       | While I personally like React, I have to say the design of the
       | library is just so awful and non-intuitive. While I can maintain
       | a legible codebase myself, as soon as juniors in my work are
       | involved I have to spend a _lot_ of time reviewing PR 's, fixing
       | changes and explaining concepts in order to make sure that the
       | application actually runs correctly and isn't, say, infinite
       | looping in a useEffect or something like that.
       | 
       | I only rant about this here because I think useCallback is pretty
       | awful design - separate functions that only exist as syntactic
       | sugar are terrible for user readability. A lot of people probably
       | know useMemo as it's quite easy to understand and used somewhat
       | frequently, but if I were to use useCallback in my code it would
       | probably cause a lot of others at my work to then have to go
       | scouring the docs to figure what the heck this hook exactly does.
       | On the other hand, just forcing users call useMemo and return a
       | function means that everyone who knows useMemo knows what's
       | happening.
       | 
       | Unless I'm completely misunderstanding how useCallback works,
       | perhaps React actually does some extra optimization under the
       | hood or for this or something.
        
         | michaelsalim wrote:
         | While I agree with with that useEffect can be non-intuitive and
         | easy to misuse, I think useCallback is pretty nice to have.
         | 
         | From what I'm aware, it's as you said. It's simply a syntactic
         | sugar for useMemo if you want to memoize functions.
         | 
         | Now if useCallback doesn't exist, you have to use useMemo and
         | pass in a function to the function. Something like `useMemo(()
         | => () => ...)`. Sure if you know what useMemo does then you'll
         | know what it does. But I have a hard time believing that
         | juniors would find that easier to read than useCallback(() =>
         | ...).
         | 
         | All I need to say to them is: "Hey, if you want to memoize a
         | function, use useCallback instead". And if I see useCallback
         | used anywhere, I know for sure that it's memoizing a function.
         | Rather than saying: "So you see that there's an extra bracket
         | there? That means that you're returning a function. Yada yada"
         | 
         | There's a grand total of 15 hooks[1], most of which you
         | probably never ever have to use. I would expect all React
         | developer to go through them all to see what they're about.
         | 
         | I would also expect them to know & remember most of the basic
         | ones: useState, useEffect, useContext, useReducer, useCallback,
         | useMemo and useRef. That's a total of 7 functions. If they
         | can't do that then I question the quality of today's
         | developers.
         | 
         | [1] https://reactjs.org/docs/hooks-reference.html
        
         | cageface wrote:
         | React works great for simple examples and small applications.
         | When you try to build something complex with good performance
         | then the difficulty goes almost vertical. It's trivially easy
         | to miss or break a stable reference somewhere and tank
         | performance or show stale data.
        
       ___________________________________________________________________
       (page generated 2022-08-30 23:01 UTC)