The ugly side of React Hooks

栏目: IT技术 · 发布时间: 4年前

内容简介:Everyone’s using React Hooks these days, functions are in and classes are out. No moreBut sadly we’ve traded “cool” for performance, and simple solvable problems likeA problem we rarely had to worry about in the past, but take a simple callback which greet

The ugly side of React Hooks

Everyone’s using React Hooks these days, functions are in and classes are out. No more this yay! (One of the reasons the React team purportedly introduced them). They allow us to easily “mixin” functionality into our component and elegantly execute code when dependencies change. They’re a nice idea.

But sadly we’ve traded “cool” for performance, and simple solvable problems like this context for much more nuanced and complicated ones.

Stale memory

A problem we rarely had to worry about in the past, but take a simple callback which greets a person:

If we later change greeting the callback is now referencing an old value. If this was a 2mb image that would also be a 2mb memory leak. Hooks have introduced one of the two hard things about programming : cache invalidation.

Infinite loops

“Add it as a dependency” the hook experts say. So let’s fetch a random number and set it to state:

Now the fetchRandomNumber function changes after every fetch and re-runs in an infinite loop.

This seems contrived but happens in any situation where you want to both read and set state in a callback which executes on mount, such as fetching some data when your page loads.

Slower render reconciliation

Most code I’ve seen rarely wraps functional components in React.memo and we’re encouraged to write naked functions inside render which will break any purity checks as they create a new function every render.

We’re told not to prematurely optimize and that it’s probably “fast enough”, because dealing with memoizing all your functions is not pretty, more costly to initialize and execute, and not trivial due to gotchas that require expert knowledge of JavaScript and hooks (we’ll get to this).

When you create methods or variables in classes they are created once per instance . It doesn’t require someone with deep knowledge of JavaScript to combine this with PureComponent to have a very efficiently updating app.

For any callbacks you do handeClick = e => { ... } and voila you’ve both solved any confusion around this and also have a “memoized” callback which didn’t involve the nightmares of useCallback .

And this gain which many people tell you not to worry about really can make a significant difference in large apps or components which render lots of elements like a data grid. In my test on a virtual grid it was over 20x faster to render memoized cells for example.

The useCallback Catch-22

We’ll just use useCallback you say. So let’s create a resize handle. In a class component the events for mouse would look something like this:

Now let’s do the same for a hook, should be simple right?

I’m sure you’ve spotted a few mistakes, let’s go over them:

  • We have a dependency on attachDocEvents and removeDocEvent in the callbacks
  • That means we also have to memoize attachDocEvents and removeDocEvents . Oh and since attach/removeDocEvents reference those callbacks we need to make them dependencies too
  • Bonus: useEffect which is only supposed to be called on unmount will be called every render since the removeDocEvents reference changes

All those considerations we didn’t previously have. Let’s try to fix them:

Okay that’s better. But there’s still a problem. Unlike classes or a normal function , const functions can only be referenced from top-down. So we cannot reference handleDragMove or handleDragComplete before they are defined. But if we move them above then they cannot reference attach/removeDocEvents . Do you know how to solve that?

Now your average developer who could write an efficient React app with classes needs to be both an expert in Javascript to understand function hoisting and reference passing, and they also need deep domain specific knowledge of React Hooks:

We simply had to “tunnel” in references to the callbacks, lovely! If you knew how to solve this you might think you’re a bonafide useRef expert. So how about this…

So you think you can useRef

Ms. Hookmeister wants to use a third party physics library for some cool effects. He knows he doesn’t need to re-run it so since he’s a hook expert he uses useRef instead of useMemo .

Now particlePhysics holds a constant reference to the expensive class he just instantiated, and he would be correct.

What he doesn’t know is that even though he always holds the first instance, a new instance is being created every render and discarded . That’s simply the nature of how JS executes. Again, requiring expert understanding to avoid expensive pitfalls.

If you don’t believe me give this a run and check the console:

All this bashing but didn’t I say hooks are a nice idea?

Totally, they can produce some clean looking code. Before hooks we didn’t have such an elegant way to mix in and re-use functionality, and we also saw a lot of ugly code in componentDidUpdate or getDerivedStateFromProps to well… derive state from props, but don’t forget that memoization isn’t even a necessity half the time with classes and you can also easily memoize functions and variables in them too.

Hooks are a clever hack to achieve a vision at the expense of API surface area, deeper JS expertise, performance and sometimes complexity. They move the React ecosystem even further away from web standards. Now we are seeing a proliferation of code which can’t even run on one half of React components let alone in a normal JS function.

So are React Hooks the way forward? Let me know what you think!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web 2.0界面设计模式

Web 2.0界面设计模式

黄玮 / 电子工业出版社 / 2013-9-1 / 59

本书集Web 2.0的发展及特点、Web 2.0界面设计模式基本理论、实际模式实践及代码实现等诸多内容于一身,具有很强的实用性。这些内容不是简单的顺序堆砌,而是以Web 2.0界面设计模式和应用为主线,其中完美地穿插了各种与之相关的Web 2.0设计理念、用户行为模式、用户体验及基于Dojo的实现方式等相关知识,真正做到将Web 2.0界面设计模式所需要的方方面面的知识有机地融为一个整体。实现不需......一起来看看 《Web 2.0界面设计模式》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具