React Best Practices

Note: This tutorial assumes you are using npx create-react-app and working within the src folder for your components. Thanks to Scott Bowler from LearningFuze for some of these tips!

Always a good idea to move components into their own folders.

Don’t just throw everything into the src folder, including components, images, css files, utility files, svgs, etc. Initially that’s okay as you start to build an app, and even prototype around. However, later you want to make sure your code is organized. If it makes sense, put everything into its own folder like so:

src/
  assets/
  components/
    App/
        App.js
        App.css
        App.test.js
    Button/
        Button.js
        Button.css
        package.json #here you can configure what should be exported to other files
  helpers/
  index.js

As Scott Bowler, of LearningFuze mentions, you can configure a package.json file per each folder with the setting:

{
    "main":"<myComponent.js>" //<-- put your component name here
}

This way if you make a Button.js component inside a Button folder, you can just configure your package.json to target Button.js as the main component when you use an import statement somewhere else in your project — you don’t need to say import Button from ./components/Button.js, you can just say import Button from ./components/Button. This is great too because you can put your Button.css file inside your Button folder and just edit the files there instead of hunting for them all in a large App.css file.

Try A React Test, Even If Just The Barebones One

Did you know your React App comes with a free App.test.js file? Usually this file is called a smoke test file, which just means a test to see if there’s any danger with your application (aka fire in the hole).

In software development, testing is a common practice, and something you should try to become familiar with especially as you begin to work in a corporate setting where many people are daily pushing to a repo. Usually before your submission can be accepted, it must go through a series of “tests” including “smoke tests”. Some of these tests you will write, others your team will write for you. If your tests pass, then your code will automatically (or manually) get pulled into the repo (though automatic is more commonplace now given Continuous Integration/Continuous Development (CI/CD)).

Try changing a few lines of code in the App.test.js file, then run either npm run test or yarn test (yarn is now recommended by React’s Team).

Test Your App
Test fails :/
Test Ran Okay!
Test Ran Okay!

Don’t Use the index as a key in a map function for rendering a component.

BAD

let listArr = [{
    link: `http://google.com`,
},
{
    link: `http://yahoo.com`,
}
...,
{
    link: `http://disney.com`
}]

listArr.map((item, index)=>(
    //DON'T DO THIS -- Not a true ID for this link
    <li key={index}>{item.link}</li>
))

^ Bad idea, because index is not a true id for the individual links here. Watch Scott Bowler talk about it here. If we modify one of these links in the list later, our key may be incorrect and point to the wrong link in the list. Instead, give your links their own id like so in the array.

GOOD


let listArr = [{
    itemId: 1,
    link: `http://google.com`,
},
{
    itemId: 2,
    link: `http://yahoo.com`,
}
...,
{
    itemId: 3,
    link: `http://disney.com`
}]

listArr.map((item, index)=>(
    //A true ID given the data
    <li key={item.itemId}>{item.link}</li>
))

Use ES6 Syntax As Needed to Clean Up Your Code, But Don’t Over Re-Factor

It’s a good idea to use the new cleaner, ES6 syntax (need a refresher? Check out Guide To ES6) to help keep your code clean and free of potential error.

Rather than use props everywhere like so:

function Header(props){
    return (
        <header>
            <a href={props.link}><img src={props.img} /></a>
            <h1>{props.title}</h1>
        </header>
    )
}

You can just use ES6 to make your code cleaner and easier to update:

const Header = ({link, img, title}) => (
    <header>
        <a href={link}><img src={img}></a>
        <h1>{title}</h1>
    </header>
)
export default Header;

Be careful not to over refactor, as sometimes that can make your code hard to understand even for yourself when coming back to read later:

//Hmm which file was this again? Oh yeah, the header..
export default ({link, img, title}) => (
    <header>
        <a href={link}><img src={img}></a>
        <h1>{title}</h1>
    </header>
)

You can export an anonymous function if you want, but it probably makes more sense to save this code into a const Header and then export default Header, as that is easier to read for a human; we know then this code is the Header code at a glance.

You don’t always need a class component, especially if you aren’t managing state

import React, {Component} from 'react'

class Header extends Component {
    render(){
        return (
            <header>
                <a href={link}><img src={img}></a>
                <h1>{title}</h1>
            </header>
        )
    }
}

This component doesn’t manage state, so why make it a class? Unnecessary overhead, especially if you pile on classes everywhere in your code. Functions are easier for JavaScript to parse, so in this case, let’s convert this component to a function instead:

const Header = ({link, img, title}) => (
    <header>
        <a href={link}><img src={img}></a>
        <h1>{title}</h1>
    </header>
)
export default Header;

^Way better! Look for ways you can reduce your own code bloat, especially if your components don’t need a state. You can also look into React Hooks, which helps you pass state through functions instead of classes. Check out this talk by Dan Abramov from Facebook on how to use React Hooks.

If you have a big project but you are managing it, try React Context API instead of Redux

You can use the Context API, which comes with React as a way to manage your application’s state and send to individual components that need them, rather than every single component nested. Phillip Troutman, one of our speakers gave a talk on the Context API, feel free to check it out!

There are three parts to using the Context API:

  1. Create the Instance (using React.createContext()).
  2. Next create a Provider and add a value to be sent to a Consumer
  3. Finally, create a Consumer that will consume the info from the provider

Example:

//Create the instance
const MyFirstContext = React.createContext()

//Create the Provider of the data
const App = () => (
    <MyFirstContext.Provider value={'Tasty Pizza'}>
        {this.props.children}
    </MyFirstContext.Provider>
)

//Create the Consumer for the data
<MyFirstContext.Consumer>
    {(contextValue) => (
        <div>I'm some div way nested, but I can get my {contextValue} without prop drilling!</div>
    )}
</MyFirstContext.Consumer>

By setting up a consumer and a provider, we can create an API that allows children components to get state (data) from a top component directly, rather than having to send data through components that don’t need them through grandparent and great-grandparent props (called prop drilling). Rather the component that needs updating can ask for it directly by wrapping it in a Consumer component and receiving the value through a consumer function. Source Phillip Troutman, YouTube.com/JavaScriptLA

Stay tuned for more best practices! Be sure to follow us on our YouTube.com/JavaScriptLA channel, Instagram.com/javascriptninja, and any other of your favorite social media!

Vijay Lead Organizer, JavaScriptLA