[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)