React js Gotchas and my two cents!

React is right now “The Cool New Thing” for the front end, So i tried it out just to see what all this fuss is about and in no time i fell in love with it. React is the GO for front end tool right now that is aimed to solve modern web design caveats and performance issues.

There are many other tools like it, specially Angular now that 2.0 is released but this post is not about WHY or IF react is better than any other. I had many friends and colleagues asking me about it since i started working with react few months ago. So first of all : React is not another MVC framework, or any other kind of framework. It’s just a library for rendering your views. If you’re coming from the MVC world, you need to realise that React is just the ‘V’, part of the equation, and you need to look elsewhere when it comes to defining your ‘M’ and ‘C’, otherwise you’re going to end up with some really yucky React code. That is why React is rarely used solo for medium to large front end projects. You will see Flux, Redux, GraphQL , Relay being used with it. I will be writing a separate post for particularly Redux with React as that is what i have been using extensively, so more on that later.

This post is also not a React tutorial post. If words Components, Props, State, JSX are unfamiliar  for you than i will suggest this amazing react tutorial on YouTube by LearnCode.academy. This tutorials helped me get started and really plunge deep into new, exciting and little bit scary world of React/ Redux /ES6 . Let’s jump into my opinionated Gotchas with React and things that if i knew, when i started coding in React, would have saved me a lot of time!

Component size matters

When ever designing components for a page the most important thing will be size and objective that component solves. So you want to show an object ( maybe a user, maybe a cat, maybe a car ) on your page, you design a component to render the object right?

Wrong!!

The best way to divide your component will be to divide it in a logical or smart component and a dumb component. If you want to show an object on your page you will need a smart component that will deal with fetching the object data from the server ( show a loader till data is fetching ? ) and a dumb component that only take data as props and renders your object, Thats it!

container-components

As shown here let smart components be the container to your pure presentational or dumb components. This will separate the logics and views part of the component and make it ridiculously simple to debug and understand.

With React 0.14 there has been a new way to define a dumb component:

const MyComponent = props => (
    <div>{props.text}</div>
);

That’s beautiful and simple. Just pass props and render the component and you are DONE!

Best ways to use ifs inside JSX

Most of the time we fetched data from server and we want to render some thing if some condition is met or some prop exists. This are few of the best ways to do it:

{ this.props.color && <MyColorComponent /> }

// Or render a multi-line component

{ !this.state.dataLoading &&
    <div className="loaded">
        {this.props.message}
    </div>
}

For complex conditions declare a variable above render method and use it to test and render the component.

Danger Note:-
Do not use a variable that may have empty string( “” ) as conditional variable for this method. It creates an empty ghost span elements, and if that span is inside a table or tbody DOM element than React will print a nice error message for you about how it can not insert a span inside the table. At which point you will be sitting there probably scratching your head and looking at your JSX not to find any span element inside your code… Trust me just use boolean values or learn the hard way!

Another scenario is to test a condition and render one or another component accordingly. Rather than going for If …else … use JS ternary operator directly in JSX:

{ this.props.favInteger == 1 ? 
    <FirstComponent /> : <LastComponent />  
}

This makes life simpler and your JSX code simpler. It’s good alternative to throwing “renderComponent()” functions here and there whenever you need to conditionally render something. JSX written like this can be read without jumping from function to function and finally figuring out whole component design…

Go for a separate function only for complex render conditions and props passing is required for that particular component.

Use PropTypes ALWAYS!

propTypes:{
  arrayProp: React.PropTypes.array,
  boolProp: React.PropTypes.bool,
  funcProp: React.PropTypes.func,
  numProp: React.PropTypes.number,
  objProp: React.PropTypes.object,
  stringProp: React.PropTypes.string,
  stringReqProp: React.PropTypes.string.isRequired,
  numberArray: React.PropTypes.arrayOf(React.PropTypes.number)
}

Use propTypes to provide validation for each prop the component will receive. Add a “isRequired” at the end where ever needed.React will print out a nice little warnings if props fail to match the declaration. Countless times this will save you hours of debugging. Make your tests fail on any PropType error.

Furthermore, this also provides a self-documenting reference for how the component should be used, and what props it needs to be passed. So don’t be a “cheapo” and pass

React.PropTypes.any

Read this article right now if you’re still not convinced.

Bind functions in constructor

If you are using ES6 ( you should be!! ) functions are not bound to React component( this ) automatically. You have to use something like:

<button onClick={this.submitForm.bind(this)}> 
    Submit 
</button>

There is one problem with this approach. Every time this button renders or re-renders a new function is created due to bind(this) at the end. If you have a lot of buttons and node elements that have handler function than there is going to be a lot of junk at run time.

To avoid this bind the functions in the constructor and pass this bound function to buttons or any other Dom elements. As constructor only run once for any component it creates on bound function for you!

constructor(props){
    super(props);

    // bind all functions of this component to this
    this.submitForm = this.submitForm.bind(this);
    [... other functions]
}

// inside JSX pass bound function
<button onClick={this.submitForm}> 
    Submit 
</button>

Webpack Enough said!

React with webpack is just the best thing that can happen to you. Webpack provides so many features that you will require to use React at its full potential and actually enjoy your development time!

There are plenty of tutorials out there for webpack and React and how everything should be setup. But there are few things i should point out that I just can not leave without while using react :

First one must be “react-html-attrs”. This plugin for webpack compiles JSX code so that you can use ‘class’ attribute rather than ugly ‘className’. If you are using something like Bootstrap and you want to copy paste Navbar code from its website you just copy and paste it PERIOD. You don’t need to go in and change every single ‘class’ to ‘className’ for it to work with react! Other such plugins that you MUST use are ‘transform-class-properties’, ‘transform-decorators-legacy’ and of course ‘es2015’. Not to forget ‘react-hot’ for hot reload.

I am a Django loving guy and i integrate Django with React multiple times. With webpack and react it is easy to setup a hot-reload React + Django setup and increase your productivity. I am probably going to make a post about “React + webpack + Django” soon.

Use ES6

Once you have setup React – Webpack workspace you get to experience the magic of ES6. There are plenty of features new to ES6 that will increase code readability and are bliss to work with.

const NOCHANGE = 'constant';
let new_variable;

Using variable ‘const’ declarations is probably one you have to use the most. JS will give you an error if your code tries to change the variable you declared as ‘const’. I am also pretty used to using ‘let’ instead of ‘var’. New ‘class’ in JS are amazing to work with. Not to forget,

import $ from 'jquery'
// or importing nested objects with {}
import { Link, browserHistory } from 'react-router'
import React, {Component} from 'react'

Spread operator are pretty handy while assigning props or state to a Component.

// pass defaultData to MyComponent with additional author field and removing error
<MyComponent data={...defaultData, author: 'Me', error : undefined } />

// initialise state from props in constructor
this.state = {...props}

Not to forget the arrow functions. When passed as an argument to map functions they become way more readable and simple.

(data) => { return <Component data={data} /> }
// Inside JSX
<button onClick={()=>{ alert("wrong button to mess with!!") }}> 
    Don't Click 
</button>

The list can go on and on… but you got the point. The only down side to using ES6 is that there is no Mixins in ES6. So if you plan on using lots of Mixins do not use class based components!

React-JSX conventions

Conventions are something that is not a MUST but a SHOULD. That is why it is good to know. Use multi line expressive code :

// use
<Component
    attribute={...}
    anotherAttribute={...}
    attributeThree={...}
    …
/>

// Rather Than
<Component attribute={...} anotherAttribute={...} attributeThree={...} />

// Multiline JSX
return (
        <div>
            <ComponentOne />
            <ComponentTwo />
        </div>
    );

Also checkout the naming conventions in React throughout the article.

Redux

As i already stated React is just the ‘V’, if you want the whole ‘MVC’ you will need to plug-in more stuff. One of the best that works with React is Redux. Redux is not React only but is used extensively with it. It takes a whole new Post to show hows, whats and gotchas for React-Redux. If your project has fairly complex front end than go for Redux.

Lastly few dislikes…

Finally there are few things you may not like about react. One of that is “dangerouslySetInnerHTML”. Which is used to render HTML markup inside any component. You will be surprised how many times you will need to use it! And every time you feel like crossing a “Danger Do Not Cross” sign on the way… Next thing is JSX comments. Right now the only way you can add a comment inside your JSX code is with:

{/* Bunch of stuff commented out here */}

That is ugly, and No you can not have a one liner comment block with ‘//’…

If you are the new guy not only to react but javascript also than you will feel your self lost between ES6 code and few old documented code.

Hope it was useful to you all. If you have more things to share about react add them in the comments bellow. I will keep adding stuff here as i keep learning, Happy Coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s