React

Last edited 158 days ago by System Writer
The purpose of this document is to help guide you through working with a potential project using the JavaScript library, . Outside of the official React documentation, you should find here personalized recommendations for using the library based on the types of projects we typically see at Kanopi. We have broken these recommendations out into common elements we tend to interact with often in client work. If something you’re looking for isn’t represented you can either submit a pull request to this repository or refer to the .

Figuring Out If React Is Right For Your Project

Using the right tool for the job is critical in navigating a successful project. Will React always be the answer? Of course not. But there are some instances where you may want to use this library over something like (for example) a collection of plugins, custom JavaScript, or another framework.
When deciding whether React is the right tool for your project, it might help to ask the following questions:
Will this project involve building a user interface that requires statefulness? In other words, will your user interface need to…react…in real time to user actions or changeable data coming from an API?
Does your project need enough reusable components to make it worth using React? React is a fairly heavy library compared with the similar Vue.
Will your project need to render large amounts of data in real time while remaining performant for the browser?
Are you building a native mobile app for iOS and/or Android? The React team also maintains React Native, a subset of React which makes it possible to write applications in JavaScript using React components that compile to native Swift and Java.
React is easily integrated into specific parts of the front-end or admin of an existing site, but it can also be used to render entire sites, effectively replacing traditional WordPress templates—although doing so requires a lot more planning and scaffolding of features (such as routing) that would normally be handled by the CMS out of the box.

Components

When building out components, it’s beneficial to understand how to construct them in the most appropriate way possible. Certain “types” of components can be written differently which can have big performance benefits on larger scale applications.

Class Components

Class Components are written in the ES6 Class syntax. When building a component using a , you are generally inferring that the component manages it’s own state or needs access to specific lifecycles hooks.
Example of a Class Component:
import React, { Component } from 'react';

class SearchInput extends Component {
constructor(props) {
super(props);
this.state = {
searchTerm: '',
};
this.handleClick = this.handleClick.bind(this);
}

handleClick(e) {
this.setState({ searchTerm: e.target.value });
}

render() {
const { searchTerm } = this.state;
return (
<div className="search-input">
<input onChange={this.handleClick} value={searchTerm} />
</div>
);
}
}

export default SearchInput;
Using class components are mostly discouraged since the introduction of . There are however some situations where you might still need a class component:
When you need access to a very specific lifecycle hook such as componentDidCatch for creating .
Some components are naturally better suited for using class components. As an example consider the following component that consumes a stream of frames:
import React, { Component } from 'react';

class Camera extends Component {
handleCameraStream = (frames) => {
// this method has proper access to props and state. Even if Camera re-renders.
cancelAnimationFrame(this.rafID);
const loop = async (now) => {
const frame = frames.next().value;
// process frame
this.rafID = requestAnimationFrame(loop);
};
this.rafID = requestAnimationFrame(loop);
};

render() {
return <CameraStream width={width} height={height} onReady={this.handleCameraStream} />;
}
}

export default Camera;
onReady is only called when the camera stream is ready and the handleCameraStream method sets up a loop, if Camera re-renders, onReady is not called again. If Camera was a functional component, everytime it re-rendered and its props/state changed, the handleCameraStream callback would not have the right scope to have access to the most up-to-date state/props as the function was bound to the first render. The alternative for using functional components is storing each frame in state through useState and process frames in a separate function but that adds complexity and unecessary re-renders every time a new frame is received.

Functional Components

A Functional Component can take the form of a in JavaScript, or a fat arrow function stored in a variable. In the past, the biggest difference between a Class Component and a Functional Component was that Functional Components were not aware of state. With the introduction of functional components are now able to handle most of the React APIs such as state, contexts, refs and lifecycle.
Functional components are the recommended way to write React components as they come with less boilerplate code, allows you to reuse stateful logic without changing component hierarchy and complex components become easier to understand by avoiding a myriad of complex logic spread between componentDidUpdate, componentDidMount and other lifecycle class methods.
The following example is the previous SearchInput component converted to a functional component using hooks.
import React, { useState } from 'react';

const SearchInput = () => {
const [searchTerm, setSearchTerm] = useState('');

const handleClick = (e) => {
setSearchTerm(e.target.value);
};

return (
<div className="search-input">
<input onChange={handleClick} value={searchTerm} />
</div>
);
};

export default SearchInput;

PureComponents

PureComponents allow for a potential performance benefit. A implements the shouldComponentUpdate lifecycle method to perform a shallow comparison of what changed in props and state since the last render.
Considering PureComponents perform shallow comparisons of previous state and new state, a component should become “pure” when theres no need to re-render the entire component (or its children) every time data changes.
Typically, you won’t need to create PureComponents as functional components and react hooks are better tools for the job. Do not use PureComponent if you are building stateless functional component and need lifecycle methods, use the useEffect hook instead.
NOTE: The performance benefits are realized when the data passed to the component is simple. Large nested objects, and complex arrays passed to PureComponents may end up degrading the performance benefits. It’s important to be very deliberate about your use of this type of component.

Routing

In most cases, you will only need routing if your React application needs to navigate between multiple layout components, render different data based on the current app location, and provide browser history. Make sure your app needs routing functionality before you consider adding a routing library.

React Router

The most popular routing library for React is . React Router provides a core library plus APIs for both DOM (web) and React Native (native iOS and Android) platforms. To use the library, install the package for one or the other API according to your application’s platform needs—the core library is included in both.
To read more about the concept of dynamic routing, with plenty of code examples to follow along with, refer to the .

Routing Accessibility

In general, routing is little more than an Ajax call to load content with a URL update. This pattern poses some accessibility problems since there is no true page reload. To overcome this and make sure our React implementations pass accessibility compliance we need to ensure a few things happen:
Update the page title.
Programmatically to the new loaded content.
(like a new page loading).
Following these steps will make sure your content and routing is readable by assistive technology.

Props and State

State in React is the lifeblood of the component. State determines how, and with what data, a component will be rendered on the page. State gives components reactivity and dynamic rendering abilities.
Props serve as a means to pass data between components. At its most basic level, props are passed to each individual component that needs to consume and utilize that data. Basic applications will likely be able to pass data using this default behavior.

State Management

As an application becomes more complex, it may become more of a hassle to pass data down to many child components. This is where frameworks like will come in. However before you reach for these third party frameworks, consider the
Context API
The React Context API is the first line of defense when your application becomes sufficiently complex, and we are faced with concerns.
Context provides a way to pass data through the component tree without having to pass props down manually at every level. This is immensely helpful for applications that are highly componentized, and need to share data with those components, regardless of where they exist within the application structure. It is crucial that you think critically about how the data in your application is to be utilized and passed around. If data simply needs to be shared, Context may be for you.
Context does not however provide the further sophisticated features of libraries like Redux. Stepping through application history, alternate UIs that reuse business logic, state changes based on actions etc. If those are things that you need in your application, the Context API may not be quite robust enough for you.
You also need to be careful with the fact that any component “connected” to a given React Context will re-render automatically when the data the context holds changes. There’s no built-in mechanism to mapStateToProps within the Context API. One way to solve this problem is to create multiple specialized contexts for you application that only stores a specific portion of you shared global state. For example, a “User” context that holds user data and a “Posts” context that holds a list of posts to be rendered on the application.
For example, consider the following UserProvider component that is responsible for fetching an user if it’s logged in and storing the user object in a React Context.
import React, { useEffect, useState, useContext, createContext } from 'react';
import PropTypes from 'prop-types';
import { fetchUser } from '../util';

export const UserContext = createContext();

export const useUser = () => {
const data = useContext(UserContext);

return data.user ? data.user : null;
};

const UserProvider = ({ children }) => {
const [user, setUser] = useState(null);

useEffect(() => {
fetchUser().then(setUser);
}, []);

return <UserContext.Provider value={{ user }}>{children}</UserContext.Provider>;
};

UserProvider.propTypes = {
children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)])
.isRequired,
};

export default UserProvider;
This component can then wrap the application tree exposing the UserContext to any child component.
import React from 'react';
import UserProvider, { useUser } from './UserProvider';

const UserMenu = () => {
const user = useUser();

return user ? 'user is logged in' : 'user is not logged in';
};

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.