
Show HN: React patterns, techniques, tips and tricks - rhakmi
https://github.com/vasanthk/react-bits
======
steve_taylor
On antipatterns:

> setState() in componentWillMount()

componentWillMount() is an anti-pattern. It is not a true lifecycle hook. It
is invoked on the server, unlike componentDidMount and friends. Anything you
do here can, and perhaps should, be done in the constructor.

> Mutating State without setState()
    
    
      handleClick() {
        // BAD: We mutate state here
        this.state.items.push('lorem');
    
        this.setState({
          items: this.state.items
        });
      }
    

There's no explanation as to why this is bad, just that it's bad and you
shouldn't do it. Because.

The real reason, in this particular example, is that any lifecycle hooks that
rely on comparing two consecutive versions of the state will not work, because
the older version of the state will have been mutated.

> Using indexes as keys... Bad... This limits the optimizations that React can
> do.

> Good... React would be able to reorder elements without needing to
> reevaluate them as much.

This isn't any incentive at all. I don't do premature optimizations and so I'd
happily use key={index} if optimization was the only issue and performance
didn't suck.

The _real_ incentive to use a value that uniquely identifies the entity being
rendered as the key, rather than an index, is to prevent the representation of
entities from being removed and added back to the DOM, so I can animate their
addition and removal, via CSS transitions, when they are actually added and
removed. Using the index as the key would make the wrong elements animate.
Also, I wouldn't want certain elements to unnecessarily go through the end of
their lifecycle only to be created again, especially if their lifecycle hooks
are tied to various side effects (e.g. API endpoints being called).

~~~
AnkhMorporkian
I mildly disagree. componentWillMount() is slightly superior to the
constructor, though only for very specific situations[0]. I would agree that
for the vast majority of people who use ES6, the difference basically doesn't
exist, but there is a real reason to use componentWillMount instead of the
constructor.

0: [https://github.com/reactjs/react-
redux/issues/129](https://github.com/reactjs/react-redux/issues/129)

Edit: You might call dispatching in a constructor an anti-pattern (or having
any side-effects at all), but quite a few people do it and it can cause _very_
subtle bugs that aren't entirely reproducible.

~~~
steve_taylor
Yeah, if you dispatch in a constructor and the effect is synchronous, it's
going to setState somewhere and React will complain, whereas if you do it from
componentWillMount, maybe React won't complain, but I'm not sure. My
understanding is that componentWillMount was needed for React.createClass, but
not so much ES6 classes. It seems a bit weird to be calling setState on a
component within the context of another component being created. As far as I'm
concerned, setState should only ever be called from an event handler, such as
user input, an endpoint returning a response, or a timer event.

~~~
AnkhMorporkian
I'm not sure how familiar with it you are, but that's kinda a result of
flux/redux architecture. There's a global state that things are passed props
to. If there is some change triggered as the result of a component being
mounted, say a globalish "there's now a tooltip active", that may modify
components including the component that triggered the change.

That's probably a simplistic example, but it really does happen.

------
acemarke
This is a good list. React's core APIs are pretty small and straightforward,
but there's a _lot_ of different patterns you can build using those APIs.

If anyone's interested, my React/Redux links list [0] points to a variety of
other useful articles for various React techniques, such as the "React
Component Patterns" [1] and "React Component Composition" [2] categories.
Those cover topics like use of `props.children`, context, the
"container/presentational" pattern, interacting with non-React code, component
lifecycle methods, Higher-Order Components, the "function-as-child / render
props" pattern, and more.

There's also some more good overviews of useful React patterns at [3], [4],
and [5] .

[0] [https://github.com/markerikson/react-redux-
links](https://github.com/markerikson/react-redux-links)

[1] [https://github.com/markerikson/react-redux-
links/blob/master...](https://github.com/markerikson/react-redux-
links/blob/master/react-component-patterns.md)

[2] [https://github.com/markerikson/react-redux-
links/blob/master...](https://github.com/markerikson/react-redux-
links/blob/master/react-component-composition.md)

[3] [http://reactpatterns.com/](http://reactpatterns.com/)

[4] [https://hackernoon.com/react-composition-patterns-from-
the-g...](https://hackernoon.com/react-composition-patterns-from-the-ground-
up-8401aaad93d7)

[5] [https://blog.pixelingene.com/2017/09/the-common-patterns-
of-...](https://blog.pixelingene.com/2017/09/the-common-patterns-of-react/)

~~~
leetbulb
+1 on the render prop style HOC. Wish I had the time to write an example, but
a good one is React Router's withRouter HOC [0]. I've used this a ton and it
works extremely well.

[0] [https://github.com/ReactTraining/react-
router/blob/master/pa...](https://github.com/ReactTraining/react-
router/blob/master/packages/react-router/modules/withRouter.js)

------
baby
Nice! I've recently tried to get into React seriously and I found myself
getting stuck pretty quickly. I tried Vue.js which seem to be popular as well
and I had a blast. I found the templates more intuitive, the documentation
easier to read and the concepts just fun to use. I ended up spending the
entire week just playing with Vue.js and making an app with it.

I was wondering what was HN's opinion on the framework. And knowing js, if I
was just once more learning a soon-to-be-dead framework and I should just
insist with React.

~~~
nicoburns
I think Vue is _probably_ safe as a technology to learn. It's definitely the
3rd framework now (behind React and Angular 2+), but it has a lot of support,
notably from Laravel which has a huge community of it's own, and from many who
quite justifiably find React/Angular2 overly complex.

It's also the case that Vue, React, and Angular 2 are in many ways more
similar than they are different, so experience with one will be helpful if you
ever need to move to using another.

Finally, at some point I would advise you to take serious look into
understanding webpack and babel and/or typescript and how to configure them.
Webpack might be 'just' the build tool, but it is the common underpinning of
pretty much all frontend development, and a lot of the complexties become a
lot more managable once you understand what it is doing.

~~~
baby
Any good resource on understanding webpack?

~~~
acemarke
Yes. The official Webpack docs [0] have been revamped, and are now pretty
good. The "Webpack Tutorials" section of my links list [1] points to many more
useful articles. I'd specifically suggest the "Webpack from First Principles"
video [2] and the "Webpack: It's Not Magic" slides [3]

Also, Sean Larkin, one of Webpack's maintainers, has put together an online
course site called "Webpack Academy" [4]. I believe the intro "Webpack Core
Concepts" course is free.

[0] [https://webpack.js.org/](https://webpack.js.org/)

[1]
[https://www.youtube.com/watch?v=WQue1AN93YU](https://www.youtube.com/watch?v=WQue1AN93YU)

[2]
[https://www.youtube.com/watch?v=WQue1AN93YU](https://www.youtube.com/watch?v=WQue1AN93YU)

[3]
[https://naomiajacobs.github.io/WebpackTalk/](https://naomiajacobs.github.io/WebpackTalk/)

[4] [https://webpack.academy/](https://webpack.academy/)

A short explanation is: you tell Webpack which file is the "entry point" to
your application. It then recursively traces all the imports from there,
creates a dependency tree, and bundles all those individual files into a
single output bundle. You can also configure it to transform files along the
way, allowing you to compile newer JS syntax into older syntax with Babel,
import images and styles into your JS bundle, and much more. It also allows
you to set up code splitting so that common code shared between different
bundles is extracted into a separate bundle file, and parts of your app can be
dynamically loaded after the initial app starts up.

------
methodover
Kind of amazing how much React has taken off these last couple of years. Was
talking to a hiring manager somewhere a few days ago who said she cared more
about someone having React experience specifically over Python/backend for the
full stack position they were hiring for. Said she'd rather they learn Python
on the job than React. Fascinating.

------
amelius
I just read the section "Conditional in JSX", and frankly I think this is
crazy. If one needs such inelegant code to deal with basic boolean logic then
I'm saying thanks, but no thanks, and I'll use some other tool than React. The
section actually speaks of an "alternate hacky approach", which says enough.

~~~
exogen
Conditional-markup solutions always look inelegant.

I'd bet this looks absolutely crazy to many developers:

    
    
        <div *ngIf="foo; then bar else baz"></div>
    

An essentially eval'd code string inside a markup attribute? That uses some
made-up language that's neither HTML nor JS?! I used to write plenty of code
like this in various template languages, and it always felt bad.

~~~
travmatt
I don't understand how you'd make a declarative style any more elegant?

    
    
      <Conditional bool={true}>
        <IfTrue/>
        <IfFalse/>
      </Conditional>
    

Doesn't seem any better

~~~
exogen
The reason OP's complaint is a bit silly is because JSX is just JavaScript and
there's no need to be doing everything in a single JSX expression in the first
place. That would be bad code just like any other situation. Do what you'd do
in normal JavaScript code: use multiple statements and put the conditional
elsewhere. Given complicated conditionals, an experienced React dev would do:

    
    
        render() {
          let foo
          if (someCondition) {
            foo = <ChildFoo/>
          }
          return (
            <Bar>
              {foo}
            </Bar>
          )
        }
    

or:

    
    
        renderChildFoo() {
          if (someCondition) {
            return <Foo/>
          }
        }
        
        render() {
          return (
            <Bar>
              {this.renderChildFoo()}
            </Bar>
          )
        }
    

or if possible, always render <Foo/> and conditionally return null in Foo's
own render() method.

~~~
couchand
> JSX is just JavaScript

No, it's not. It's the bastard child of XML and JavaScript. I agree that your
examples are about the best you can do with JSX. But actually just JavaScript
is much easier:

    
    
      render() {
        return Bar(someCondition && Foo())
      }
    

or

    
    
      render() {
        return Bar(someCondition ? Foo() : null)
      }
    

That's not quite hyperscript but it's not far from it.

~~~
exogen
Digs at JSX aside, I think you may have lost track of what this thread was
about: complicated nested conditionals. These are a pain to do in a single JS
expression, JSX or hyperscript or otherwise – even in your example. In JSX
your simple example would look just as nice:

    
    
        <Bar>{someCondition && <Foo/>}</Bar>

