The React Cheatsheet for 2022

Whether you‘re new to React or looking to take your skills to the next level, having a solid grasp of the fundamentals is essential. React is a hugely popular library and in active development, so it‘s important to stay up-to-date with the latest features and best practices.

In this comprehensive guide, I‘ve distilled the key React concepts and techniques you need to know for building modern web apps in 2022. Think of it as your handy reference for writing clean, efficient React code. Let‘s jump in!

React Elements and JSX

At the core of every React app are React elements. Elements are the smallest building blocks describing what you want to appear on screen.

React elements are written in a syntax called JSX, which looks like HTML:

const element = ;

However, JSX is really just syntactic sugar for creating React elements using JavaScript. The code above compiles to:

const element = React.createElement(‘h1‘, null, ‘Hello, world!‘);

A few things to note about JSX syntax:

  • Use camelCase for attribute names (e.g. className instead of class)
  • Use curly braces {} to embed expressions
  • Wrap multi-line JSX in parentheses to avoid automatic semicolon insertion
  • Elements must be closed explicitly (e.g. <br /> not <br>)

Here are some more JSX examples:

// Embedding expressions
const name = ‘Josh Perez‘;
const element = ;

// Specifying attributes
const element = <img src={user.avatarUrl}></img>;

// Rendering child elements
const element = (
  <div>

    <h2>Good to see you here.</h2>
  </div>
);

Components and Props

React allows you to split the UI into independent, reusable pieces called components. Components let you build self-contained modules that encapsulate both the structure and logic of the UI.

The simplest way to define a component is as a JavaScript function that accepts a single "props" object and returns a React element:

function Welcome(props) {
  return ;
}

Components can also be defined as ES6 classes:

class Welcome extends React.Component {
  render() {
    return ;
  }
}

Components accept arbitrary inputs called "props" (short for properties) and return React elements describing what should appear on screen. Props are read-only and immutable.

Here‘s an example of composing components and passing props:

function App() {
  return (
    <div>
      <Welcome name="Sara" />      
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById(‘root‘)
);

State and Lifecycle

In addition to props, components can have internal state data that determines how the component renders and behaves. State is private to a component and can change over time, usually in response to user actions.

The setState() method is used to update a component‘s state and re-render the component with the updated state. Here‘s a simple example of a stateful component:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({      
      date: new Date()
    });
  }

  render() {
    return (
      <div>

        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

This example also demonstrates some of React‘s lifecycle methods:

  • componentDidMount() runs after the component output has been rendered to the DOM
  • componentWillUnmount() is invoked when the component is removed from the DOM
  • render() is the only required method in a class component and returns the React elements to render

Other commonly used lifecycle methods include:

  • shouldComponentUpdate() lets you optimize performance by skipping re-renders
  • componentDidUpdate() runs after updates are flushed to the DOM

Hooks

Hooks are a new addition in React 16.8 that let you use state and other React features without writing a class. Hooks allow you to "hook into" React state and lifecycle methods from function components.

The useState hook lets you add state to functional components:

import { useState } from ‘react‘;

function Example() {
  // Declare a new state variable, which we‘ll call "count"  
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

The useEffect hook lets you perform side effects in functional components, similar to componentDidMount, componentDidUpdate, and componentWillUnmount:

import { useState, useEffect } from ‘react‘;

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:  
  useEffect(() => {    
    // Update the document title using the browser API    
    document.title = `You clicked ${count} times`;  
  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Other built-in hooks include:

  • useContext for subscribing to React context
  • useRef for creating a mutable ref object
  • useMemo for expensive calculations you want to cache
  • useCallback for expensive callbacks you want to cache

Custom hooks allow you to extract component logic into reusable functions. For example, here‘s a custom hook that subscribes to a friend‘s online status:

import { useState, useEffect } from ‘react‘;

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

Context

Context provides a way to pass data through the component tree without having to pass props down manually at every level. It‘s designed to solve the problem of "prop drilling".

To create context, use the React.createContext() method:

const ThemeContext = React.createContext(‘light‘);

The Provider component allows consuming components to subscribe to context changes:

<ThemeContext.Provider value="dark">
  <Toolbar />
</ThemeContext.Provider>

To consume context in a class component, use the contextType class property or a <Context.Consumer>:

class ThemedButton extends React.Component {
  static contextType = ThemeContext;  
  render() {
    return <Button theme={this.context} />;
  }
}

To consume context in a function component, use the useContext hook:

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <Button theme={theme} />;  
}

Styling

There are several ways to style React components:

Inline styles using the style attribute:

<div style={{ color: ‘red‘, fontSize: 12 }}>
  Hello World
</div>

Regular CSS with class names:

<div className="menu navigation-menu">

</div>

CSS Modules to scope styles at the component level:

import styles from ‘./Menu.module.css‘;

function Menu() {
  return (
    <div className={styles.menu}>
      <h1 className={styles.title}>
        Here‘s a title!
      </h1>
    </div>
  );
}

CSS-in-JS libraries like styled-components:

import styled from ‘styled-components‘;

const Menu = styled.div`
  display: flex;
  width: 300px;  
`;

const Title = styled.h1`
  color: red;
  font-size: 16px;
`;

function MyComponent() {
  return (
    <Menu>
      <Title>Here‘s a title!</Title>  
    </Menu>
  );
}

Other Essential React Concepts

A few other key React concepts worth knowing:

Fragments let you group a list of children without adding extra nodes to the DOM:

return (
  <React.Fragment>    
    <ChildA />
    <ChildB />
    <ChildC />
  </React.Fragment>
);

Higher-Order Components (HOCs) are functions that take a component and return a new component with some additional functionality:

function withLogger(WrappedComponent) {
  return class extends React.Component {
    componentDidUpdate(prevProps) {
      console.log(‘Current props: ‘, this.props);
      console.log(‘Previous props: ‘, prevProps);
    }
    render() {
      return <WrappedComponent {...this.props} />;    
    }
  }
}

React Router is the de facto library for routing in React apps:

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
          </ul>
        </nav>

        <Route path="/" exact component={Home} />        
        <Route path="/about" component={About} />
      </div>
    </Router>
  );
}

Performance Optimization

React is fast by default, but there are some techniques you can use to speed up your apps:

Use the shouldComponentUpdate lifecycle method to prevent unnecessary re-renders:

shouldComponentUpdate(nextProps, nextState) {
  return nextProps.id !== this.props.id;
}

Use the React.memo higher-order component to wrap functional components and skip re-rendering them if the props haven‘t changed:

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

Testing and Debugging

There are many tools and libraries in the React ecosystem for testing and debugging your apps.

Jest is a JavaScript testing framework popular in the React community. It lets you write unit tests for your components:

import React from ‘react‘;
import MyComponent from ‘./MyComponent‘;
import renderer from ‘react-test-renderer‘;

it(‘renders correctly‘, () => {
  const tree = renderer
    .create(<MyComponent page="http://www.facebook.com">Facebook</MyComponent>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

React Testing Library builds on top of DOM Testing Library by adding APIs for working with React components:

import { render } from ‘@testing-library/react‘

test(‘renders a message‘, () => {
  const { container, getByText } = render(<Greeting />)
  expect(getByText(‘Hello, world!‘)).toBeInTheDocument()
  expect(container.firstChild).toMatchInlineSnapshot()
})

The React Developer Tools browser extension lets you inspect the React component hierarchies in the Chrome and Firefox Developer Tools:

React DevTools screenshot

Accessibility

Making your web apps accessible is important so that all users, including those with disabilities, can use them. Some tips for improving the accessibility of your React app:

Use semantic HTML elements like <header>, <nav>, <main>, <footer>, etc.

Provide text alternatives for images and other non-text content using the alt attribute.

Use landmarks like role="main", role="navigation", etc. to define page regions.

Label inputs using the htmlFor attribute (or nested labels).

Use the lang attribute to specify the language of the page.

Ensure your content is keyboard navigable and that focus is managed properly.

Ecosystem and Tooling

Lastly, let‘s look at some of the useful libraries and tools in the React ecosystem:

  • Redux for managing global application state
  • MobX for simple, scalable state management
  • Axios for making HTTP requests
  • Lodash for utility functions
  • Formik for building and validating forms
  • React Router for declarative routing
  • Gatsby for building static websites with React
  • Next.js for server-rendered React apps
  • Material-UI and React Bootstrap for component libraries
  • Storybook for developing and testing components in isolation
  • ESLint for catching errors and enforcing code style

That covers all the essential React concepts and techniques you need to know as a professional developer in 2022. I hope this guide has been helpful! Let me know if you have any other questions.

Similar Posts