
React.js pure render performance anti-pattern - mxstbr
https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f
======
cloverich
(tl;dr) The title is getting a lot of flack but I think there are two good
patterns highlighted: 1) Avoid creating functions in React render and 2) Learn
about and use defaultProps.

1: Example of arrow functions + Class property initializer:
[http://babeljs.io/blog/2015/06/07/react-on-
es6-plus/](http://babeljs.io/blog/2015/06/07/react-on-es6-plus/) 2: Default
Props: [https://facebook.github.io/react/docs/reusable-
components.ht...](https://facebook.github.io/react/docs/reusable-
components.html#default-prop-values)

------
andrewingram
Is it really an anti-pattern when you're just writing code that depends on
equality without understanding how equality works?

There's probably a lesson to be learned in here, but if I wrote an article
every time I wrote bad code, I wouldn't have time to write any bad code ;)

Edit: This particular issue is pretty common, and it's good to draw attention
to it, but let's just call it what it is - a common bug.

~~~
ashearer
"Anti-pattern" sounds close enough, as shorthand, when "bug" might cause
readers to file the article incorrectly. The author is warning others that a
normally-unremarkable JavaScript idiom causes suboptimal performance in this
particular case, and it's likely not to present itself as a bug (having no
visible symptoms on smaller pages and no impact on functionality otherwise).
Putting aside whether suboptimal performance should always be classified as a
bug, there are many ways to accidentally break equality comparisons (despite a
full understanding of them), and now my eyes are primed to catch one more
pitfall. I appreciate when that happens for reason that doesn't involve hard
experience.

~~~
andrewingram
I think calling it a common pitfall might be the most descriptive. I've
certainly made the mistakes the article mentions, but I'd never have
considered it a pattern. To me a pattern in this context is a repeated
practice, workflow or solution.

------
fiatjaf
This is not an anti-pattern, it's a mistake you made.

------
danmaz74
We just use Immutable.js in our Redux stores. Then, using PureRenderMixin is
trivial. You just need to be careful not to use the vanilla reducer composer
from Redux.

~~~
darklajid
Can you expand on "You just need to be careful not to use the vanilla reducer
composer from Redux." a bit more? Is that 'combineReducers' from Redux?

What's wrong with that? What are the alternatives?

~~~
jonesetc
combineReducers is for taking plain objects and returning another plain
object. With immutable you need to either write your own combineReducers or
use one that someone else has made that taks immutable objects and returns an
immutable object.

~~~
darklajid
Wait - we're talking about the result of the combination?

If you follow a 'get started with redux' thing and end up with a root reducer
that uses combineReducers: You're talking about the outermost 'state' object?
Because any reducer that you write can certainly accept/understand/return
immutables, right?

If I picked that up correctly: Is that a problem for a single combineReducers
at the root? Because if all the properties of that thing are immutable,
wouldn't you get the cheap identity based comparison benefits whenever you
pass on props.foo in your store-aware component?

~~~
danmaz74
Yes, it's the actual combiner that can't create an Immutable object.

------
leomelin
How do you avoid the e => fn() here in stateless functional component? This is
very common case and I can't see other workaround than to use redux
mapStateToProps, or without redux maybe mapProps from recompose. Or to use
something stupid like writing the item.id into data-attr-id on the li -element
and digging out the id -value in the event handler...

    
    
      const List = props => 
        <ul>
          props.items.map(item =>
            <li onClick={e => props.itemClicked(item.id)}>{item.name}</li>
          )
        </ul>

------
johnhenry
I think that some of the issues that you're running into might be mitigated by
taking advantage of the "key" attribute on repeated elements. There's more
here: [https://facebook.github.io/react/docs/multiple-
components.ht...](https://facebook.github.io/react/docs/multiple-
components.html#dynamic-children)

------
simplify
Is it wrong for me to think that having a thousand Cell elements on the page
is the true anti-pattern? The user can really only see maybe 10-20 at one
time. The cost of re-rendering on 15 rows should be trivial enough not to
worry about creating a callback function in render.

Edit: To elaborate, you can solve this by using pagination (a common
solution), or, if you want the user to be able to scroll and not click,
occlusion culling. Someone out there must have written an occlusion culling
library for React by now, surely.

~~~
simplify
Could someone explain the downvotes? I'd genuinely like to know what my
comment is doing wrong.

------
_alexander_
Where is anti-pattern?

