5 Recommended ReactJS Tips and Best Practices

React.js tips from top React developers and engineers.

Nicolas Adrien
Bits and Pieces

--

React is something every front-end developer should have in their tool belt. Some new concepts need to be learned, and a few things we used to apply in traditional MVP apps need to be unlearned.
That’s why I reached out to you to share knowledge and offer the best tips from some top React developers and engineers. Let’s get started!

  1. How to deal with this Reference inside the promise?

While working with React.js, chances are you’ve faced a problem with how to access this from inside the promise. For example, as exhibited in the code below, 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’s more than one solution to determine this reference inside the promise. The earlier approach would be setting the self = this reference. While this would work, the recommended solution, which is more incline 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 described above, is a much reliable way to allow a user of this to make reference to React.Component classes, as we can analyze below:

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

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

2) How to use rc-chartjs or react-chartjs in React.js Application running Under webpack-dev-server?

Another widely observed scenario when working with React.js is the development of apps using webpack-dev-server with hot reloading support. Individually, for this, I’m using a series of components that can b accessed in a React Transform Boilerplate.

After you’ve hot reloading working rightly, you may end up facing issues with some JavaScript references inside third-party React.js components, like react-chartjs component highlighted above in the title. In this particular case, most probably react-chartjs, and its fork rc-chartjs, have a similar kind of problem: they can’t reach a reference to a window object when scripts is bundled by webpack and served by webpack-dev-server.

To fix this, I used the import-loader provided by Webpack. Look at the …. Configuration example below:

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

As you can see, we’re injecting this reference to a window object straight into chart.js library.

3) How to use dependency injection in React.js application?

As JavaScript developers, dependency injection is one of the finest software design practices that we have at our disposal. By using dependency, we can avoid multiple duplicated code in the application, largely regarding services initialization and configuration.
In the example below, I made use of a dependency injection library called Jimple to handle the injection of my service layer code into the components. But first, I need to ensure the Jimple container is injected rightly on each React.js component.

Let’s have a look first on container description:

import Jimple from ‘jimple’;import { UsersService } from ‘./services/UsersService’;export let container = new Jimple();container.set(‘API_URL’, function © {
return ‘http://localhost:8080/api';
});container.set(‘API_VERSION’, function © {
return ‘1.0.0’;
});container.set(‘USERS_SERVICE’, function © {
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 named as createElement which allows us to advance the container to component 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 as we will do 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>
}
}

4) Avoid className and Style in your components

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

  • You’ve to consider what style it requires to make it look the way you want.
  • You’ve to understand the default set of styles, in order to know the styles from the beginning point.
  • You can pass any kind of styles that don’t make sense and may interrupt 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’ve to know that we need to pass the classes btn-primary. Also, we could pass any other className that would not make wisdom, like make-this-look-like-a-pig.

Instead, consider the following code snippet:

<Button primary>Press me!</Button>

In the code pattern above, we use a custom Button component that internally may use the initial 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 principal 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’re passing to the div. Moreover, we can pass any other style that we want, including styles that do not 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 encased that piece of the layout into different components, which hide that style implementation detail away from us, and we simply use them. This specific piece of code doesn’t even care if the sidebar is on the right or on the left.

One more example, exhibiting a successful notification:

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

Same issue as the first example. We need to know that those classes need to be implemented.

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

Using a custom notification component that takes 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 rethink of any class convention.

One final example. Let’s consider how we could simplify layouting a form by defining a Layout Component that postulates the width of its children.

Here we first layout three inputs in a similar row, where the first two have equal size, and the third one is half of the size of the others, with the row taking the whole 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 consider how avoiding styles and classNames forces you to distinguish styling concerns like how it looks vs. how it lays out, which suggests you’ll have different components to enforce each. In the last example, the Input and Buttons have no clue how they will lay out. That’s the job for a parent component.

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

It will be good to leave styles and className to be used in leaf-most components and create a set of components that will build look and feel, and another set that will define layout.

When you execute this, it will become much simpler to generate new components, pages, and views of your app, since you’ll only need to arrange your set of appearance and layout of components and pass them the right props without even anticipating about CSS or styles.

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

5. Create tiny components that just do One Thing

Generate small components that halt particular parts of your page or add specific new behavior to your UI. You’ll be able to consider each piece individually, and you will even be able to benefit from performance optimization like shouldComponentUpdate in a more granular manner, or other lifecycle components.
Moreover, they will become more reusable across your application. Not to indicate to the React community, if they’re generic enough.

A few hints to know if you separate your component:

  • Keep your render function short and simple. You can split the render function into various functions in a similar component, but if it makes sense, try splitting those render chunks into separate components.
  • Are you working with application state logic and also a presentation in the same component? Attempt 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 require to be updated much more frequently than others? Extract that chunk into a separate component, and try to localize the state updates inside (if it makes sense), or use shouldComponentUpdate in the other components to prevent any unnecessary re-renders.
  • Do you have a form with various sections and fields but you really don’t care about all the intermediate state, Extract that form into its own component (or even varying sections of the form into their own components) that accept the primary values as properties, and have an onSubmit callback property that’s called with end 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 uses uncontrolled components or implement the component internal state.
  • Are you doing a lot of styling for layouting a set of components? Exact that into layout components that have configurable yet predefined layouts and place your components as children of them.
  • Are you adding behavior to some component through the state like collapsing, expanding, hovering, or making it pop over? Move that behavior into separate components that take a single child which is a function to render, and sets the state via patterns to that function, like:
<Hoverable>
{hovered => <div>{hovered ? “I’m hovered!” : “I’m not hovered”}</div>}
</Hoverable>

Conclusion

There are precisely several reasons to split your current component into more. Remember, components in React are quite like functions. You can split a function into many. Also, you can compose or combine them in any way you want, and still get the same result.

For coronavirus updates, you can visit CNBC Live Stream.

Share & Manage Reusable React Components with Bit

Use Bit (Github) to share, document, and manage reusable components from different projects. It’s a great way to increase code reuse, speed up development, and build apps that scale.

Example: React components shared on Bit

--

--