React.js Best Practices and Tips by Toptal Developers

Share

This resource contains a collection of React.js best practices and React.js tips provided by our Toptal network members.

This resource contains a collection of React.js best practices and React.js tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging React.js techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.

React is a library that helps to create web UIs that has revolutionized the way we think about apps. Borrowing ideas from declarative, reactive and functional programming, it makes developing highly interactive UIs a breeze. As such, it is something every frontend developer should have in their tool belt.

As most developers transition to this way of doing things, some new concepts need to be learned, and some things we were used to doing in traditional MVC apps need to be unlearned. That’s why we reached out to our top React developers and engineers to share their knowledge and offer their best tips.

How to Use `rc-chartjs` or `react-chartjs` in React.js Application Running Under `webpack-dev-server`?

Another very common scenario when working with React.js is the development of applications using webpack-dev-server with hot reloading support. Personally, for this I’m using a series of components that can be found in a React Transform Boilerplate.

Once you get hot reloading working properly, you may eventually face issues with some JavaScript references inside third-party React.js components, like react-chartjs component mentioned in the title. In that case, most probably react-chartjs, and its fork rc-chartjs, have the same problem: they can’t find a reference to a window object when scripts is bundled by webpack and served by webpack-dev-server.

To fix this, I used import-loader provided by webpack. Take a look at the webpack configuration example below:

module: {
  loaders: [
    {test: require.resolve('chart.js'), loader: 'imports?this=>window'}, 
  ]
}

As you can notice, we are injecting this reference to a window object straight into chart.js library.

Contributors

Rogério Araújo

Freelance React.js Developer
Brazil

Rogério is a full-stack developer with 15 years of experience with software development and architecture. He has worked on several projects for customers in Brazil and globally. The range of projects include mobile, applications, desktop, and enterprise search applications.

Show More

Get the latest developer updates from Toptal.

Subscription implies consent to our privacy policy

How to Use Dependency Injection in React.js Application?

Dependency injection is one of the best software design practices that we have at our disposal as JavaScript developers. By using dependency injections we can avoid a lot of duplicated code in the application, mostly regarding services initialization and configuration.

In the example below, I used a depenedecy injection library called Jimple to manage the injection of my service layer code into components. But first, I need to make sure the Jimple container is injected correctly on each React.js component.

Let’s take a look first on container definition:

import Jimple from 'jimple';

import { UsersService } from './services/UsersService';

export let container = new Jimple();

container.set('API_URL', function (c) {
  return 'http://localhost:8080/api';
});

container.set('API_VERSION', function (c) {
  return '1.0.0';
});

container.set('USERS_SERVICE', function (c) {
  return new UsersService(c.get('API_URL'), c.get('API_VERSION'));
});

Next, on the Router component we need to inject the container on each Component rendered by its routes. For this we defined a function called createElement which allows us to forward the container to components as a property:

import { Router, IndexRedirect, Route, History } from 'react-router';

import { container } from './container';

class MoneyApp extends React.Component {
  render() {
    return <div>{this.props.children}</div>
  }
}

// Pass container as prop to children components
function createElement(Component, props) {
  return <Component container={container} {...props}/>
}

render((
<Router history={history} createElement={createElement}>
  <Route path="/" component={MyApp}>
    <Route path="/login" component={Login} />
    <Route path="/dashboard" component={Dashboard}>
      <Route path="/dashboard/overview" component={Overview} />
    </Route>
    <IndexRedirect to="dashboard" />
  </Route>
</Router>),
document.getElementById('app'));

In the end, we can retrieve the dependencies like in the example below:

class Overview extends React.Component {
  constructor() {
    super();
    this.state = { pending: [], lastMonths: [] }
  }
  componentDidMount() {
    let service = this.props.container.get('SERVICE');
    service.yourMethod();
  }
  render() {
	return <div><span>Some content</span></div>
  }
}

Contributors

Rogério Araújo

Freelance React.js Developer
Brazil

Rogério is a full-stack developer with 15 years of experience with software development and architecture. He has worked on several projects for customers in Brazil and globally. The range of projects include mobile, applications, desktop, and enterprise search applications.

Show More

Can Views Listen to Actions by Using Flux?

When starting to work with a new framework, many developers often fall into the trap of using it in a way it was not designed for, or applying practices and patterns learned from the usage of previous ones. As React.js and Flux come to challenge some of those practices, it’s possible that we’re not doing what’s best with it at the beginning. Let’s see this in the following scenario.

In Flux, a thing called “dispatcher” is in charge of notifying all the stores that some action has happened in the app, so that those stores are able to update the app state and in turn notify the views that care about those stores that there’s been an update, so that those views re-render themselves. So that ‘dispatcher’ acts basically as an event-bus.

A new React.js developer, coming from a previous MVC library or framework, would very quickly want to listen to those actions or abuse that “dispatcher” for triggering events that are not something that needs to be listened to by the stores. Something like this:

componentDidMount() {
  myDispatcher.register((action) => {
  	if (action.type === "whatImListeningFor") this.doSomething();
  });
}

If you’re in that situation or you’re working in a project where you have this scenario, think twice. In this architecture, the state is the source of truth, and for anything meaningful that happens in your app, you should have some state to represent some change that was made by that thing that happened.

Some things may initially seem wrong to model as state, or may make more sense to model as event-based instead of state-based. For example, animation is something that you may think should be triggered by an event, and not by a flag in the state saying animating: true or something like that. But in reality, an animation is actually a visualization of a transition between states. So instead of listening to events, in this case we could listen to state transitions to trigger the animation in a particular component. How can we do that, you say? Well, React provides us with some lifecycle hooks that allows us to do what we want: componentWillReceiveProps, componentWillUpdate, componentDidUpdate, are the ones to look for in the previous link. Those allow us to compare between previous props and new props (or previous local state, and new local state) and do something when that happens. We can trigger an animation there, or anything we want. That way we could be also able to detect the transition back to the other state, and revert the animation for example. It gives us more control on what to do and stay in sync with the state of the application, compared to having a single ad-hoc event triggered from some other place that wants to say something to us, and couples the emitter of that event with the caller.

From personal experience I haven’t yet found the need for emitting events, and have always been able to solve those problems with listening to state transitions. If there are use cases that really need that, trust me, they are very rare and you should consider trying the approach explained here before even attempting that. You can drop a comment here below if you need help for your particular use case and you don’t know what to do.

Having said that, it’s worth mentioning that the state we’re talking about doesn’t necessarily mean it should be state living in the store. If it doesn’t make sense to put it there, you can directly work with the local component state (this.state and this.setState) and have the same way of working (as mentioned before, componentWillUpdate and componentDidUpdate work with local state too). If then you see that it makes sense to move it to a store (because it is shared with some other component), you can easily upgrade and modify it via actions instead of directly in the component.

To sum it all up, avoid using the dispatcher as an event bus for events that are not handled by stores, try to listen instead for state transitions using the lifecycle hooks provided by React in your components. Don’t abuse the dispatcher just because it’s an event emitter, its role is very specific.

Contributors

Leonardo Andrés Garcia Crespo

Freelance React.js Developer
United Kingdom

Leonardo is a lifelong fan of technology and is always trying to learn something new while keeping up to date with his favorite technologies. He has a very proactive personality, and he's always building something. He is currently heavily working with technologies such as React and GraphQL.

Show More

Avoid className and Style in Your Components

You want your application to have a consistent look and feel, so you don’t want to pass around classNames and styles in an ad-hoc manner. Having the possibility to pass any style or className to a component means that:

  • You have to consider what style it needs to make it look the way you want.
  • You have to know the default set of styles, in order to know the styles from first point.
  • You can pass any kind of styles that don’t make sense, and may break your UI.

Let’s see what I’m talking about with some examples.

Let’s render a ‘primary’ button to start:

<button type=”button” className=”btn btn-primary”>Press me!</button>

In the above example, we have to know that we need to pass the classes btn and btn-primary. Also, we could pass any other className that would not make sense, like make-this-look-like-a-pig.

Instead, consider the following code snippet:

<Button primary>Press me!</Button>

In the code example above we use a custom Button component that internally may use the first approach, but just exposes a primary Boolean property like this:

class Button extends React.Component {
  render() {
    // Using https://github.com/JedWatson/classnames
    var className = classNames(‘btn’, this.props.primary && ‘btn-primary’);
    return <button type=”button” className={className} onClick={this.props.onClick}>
      {this.props.children}
    </button>;
  }
}

Let’s consider another example. We want to render the main content on the left, and the sidebar on the right:

<div style={{float: ‘left’, width: ‘80%’}}>
  Main content
</div>
<div style={{float: ‘left’, width: ‘20%’}}>
  Sidebar content
</div>

What if we want to use flexbox? We need to come here and modify the styles we are passing to the div. Also, we can pass any other style that we want, including styles that don’t make any sense or that we don’t intend someone to use.

Now instead, take a look at the following code:

<Main>
  Main content
</Main>
<Sidebar>
  Sidebar content
</Sidebar>

We wrapped that piece of layout into separate components, which hide that style implementation detail away from us, and we just use them. This particular piece of code doesn’t even care if the sidebar is on the right or on the left.

Another example, showing a successful notification:

<div className=”notification notification-success”>
  A good notification
</div>

Same problem as the first example. We need to know that those classes need to be used.

<Notification type=”success”>
  A good notification
</Notification> 

Using a custom notification component that accepts a type, and which can be validated via React.PropTypes to just be any value of a predefined set makes the user of this component not need to remember any class convention.

One final example. Let’s see how we could simplify layouting a form by defining a Layout component that specifies the width of its children.

Here we first layout out three inputs in the same row, where the first two have equal size and the third one is half the size of the others, with the row taking full width of the container. Then we render another row with a button taking full width.

<Layout sizes={[1, 1, 0.5]}>
  <Input placeholder=”First Name” />
  <Input placeholder=”Last Name” />
  <Input placeholder=”Age” />
</Layout>
<Layout>
  <Button>Submit</Button>
</Layout>

Please notice how avoiding styles and classNames forces you to separate styling concerns like how it looks vs how it lays out, which means you’ll have different components to enforce each. In this last example, the Input and Buttons have no idea how they will be laid out. That’s the job for a parent component.

Think about components’ properties as their API. Exposing styles or classNames is like exposing an ‘options’ object which can have hundreds of options. Do you really want that for your own components? Do you really want to think about each possible option when you use them?

It’s better to leave styles and className to be used in your leaf-most components, and generate a set of components that will build your look and feel, and another set that will define your layout.

When you do this, it will be much more simple to create new components, views, and pages of your application, since you’ll just need to arrange your set of appearance and layout components and pass them the correct props without even thinking about CSS or styles.

And as an added benefit, if you want to tweak the styles or change the look and feel of your application, you will mostly just need to modify the library components. Also if you keep the same API for them, the components that use them will remain untouched.

Contributors

Leonardo Andrés Garcia Crespo

Freelance React.js Developer
United Kingdom

Leonardo is a lifelong fan of technology and is always trying to learn something new while keeping up to date with his favorite technologies. He has a very proactive personality, and he's always building something. He is currently heavily working with technologies such as React and GraphQL.

Show More

Create Tiny Components That Just Do One Thing

Don’t have big components that render a bunch of stuff directly. It makes your component hard to maintain and it also makes it hard to take advantage of React’s optimizations, since it still needs to create a lot of elements and calculate the diff. Also, having components with big render methods means that the component is doing way too much work. Just like having a function with a long body. Instead consider splitting your components into many little components.

Create small components that render specific parts of your page or add a particular new behavior to your UI. You’ll be able to think of each piece individually, and you’ll even be able to benefit from performance optimizations like shouldComponentUpdate in a more granular way, or other lifecycle components. Also, they’ll become more reusable across your application. Not to mention to the React community, if they’re generic enough.

Some hints to know if you should separate your component:

  • Keep your render function small and simple. You can split the render function into several functions in the same component, but if it makes sense try splitting those render chunks into separate components.
  • Are you dealing with application state logic and also presentation in the same component? Try to separate it into a component that just handles the state and one or several components that handle the presentation, where the state is passed as a property to the child components.
  • Do you have some elements in your render method that need to be updated much more often than others? Extract that chunk into a separate component, and try to localize the state updates inside (if it makes sense), or implement shouldComponentUpdate in the other components to avoid unnecessary re-renders.
  • Do you have a form with lots of sections and fields but you really don’t care about all the intermediate state, just the initial and on submit value? Extract that form into its own component (or even different sections of the form into their own components) that accept the initial values as properties, and have an onSubmit callback property that is called with the final values of the form, making the parent not need to re-render every time an intermediate change in the form occurs. Internally in those section components, either use uncontrolled components or use the component internal state.
  • Are you doing a lot of styling for layouting a set of components? Extract that into layout components that have configurable but predefined layouts and place your components as children of them.
  • Are you adding behavior to some component via state like hovering, collapsing, expanding, or making it pop over? Move that behavior into separate components that accept a single children which is a function to render, and sets the state via params to that function, like:
<Hoverable>
    {hovered => <div>{hovered ? “I’m hovered!” : “I’m not hovered”}</div>}
</Hoverable>

There are definitely a lot more reasons to split your current component into more. Remember, components in React are pretty much like functions, you can split a function into many and compose or combine in any way you want, and still achieve the same result.

Contributors

Leonardo Andrés Garcia Crespo

Freelance React.js Developer
United Kingdom

Leonardo is a lifelong fan of technology and is always trying to learn something new while keeping up to date with his favorite technologies. He has a very proactive personality, and he's always building something. He is currently heavily working with technologies such as React and GraphQL.

Show More

How to Deal with `this` Reference Inside the Promise?

When working with React.js, chances are you have faced a problem how to access this from inside the promise. For example, like shown in the code bellow, one of the problems could be this is resolving inside the promise as undefined :

class Component extends React.Component { 
  componentDidMount() {
    axios.get('http://…').then(function(data) {
      this.setState( { name: data.blah } );
    });
  }
}

There is more than one solution to resolve this reference inside the promise. The old approach would be setting the self = this reference. While this would work, the recommended solution, which is more inline with ES6, would be to use an arrow function here:

class Component extends React.Component { 
  componentDidMount() {
    let component = this;
    axios.get('http://…').then(function(data) {
      component.setState( { name: data.blah } );
    });
  }
}

The arrow syntax, as stated above, is a much smarter way to allow use of this to make reference to React.Component classes, as we can see below:

class Component extends React.Component { 
  componentDidMount() {
    axios.get('http://…').then(data => {
      this.setState( { name: data.blah } );
    });
  }
}

Please note, instead of using function(data) { //body }, we used data => { //body }, and in this case this reference won’t get the promise instance back.

Contributors

Johannes Stein

Freelance React.js Developer
United Kingdom

Johannes is a highly skilled software engineer with extensive knowledge of JavaScript, web technologies, and cross-platform development. He is extremely passionate about open source software and is skilled in software architecture.

Show More

Rogério Araújo

Freelance React.js Developer
Brazil

Rogério is a full-stack developer with 15 years of experience with software development and architecture. He has worked on several projects for customers in Brazil and globally. The range of projects include mobile, applications, desktop, and enterprise search applications.

Show More

Submit a tip

Submitted questions and answers are subject to review and editing, and may or may not be selected for posting, at the sole discretion of Toptal, LLC.

* All fields are required

Toptal Connects the Top 3% of Freelance Talent All Over The World.

Join the Toptal community.