Back

/ 7 min read

React.js Cheat Sheet: A Quick Guide to Core Concepts

Setup

Project Initialization

First things first, to setup a react.js project, you need to run the following command:

Terminal window
npx create-react-app@latest app-name

For typescript support:

Terminal window
npx create-react-app app-name --template typescript

Overview

There’s three main parts to understanding the react app structure.

The index.html file sent by the server. Defines the root element targeted by React to load it’s application.

public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

The node.js entry point. This is what identifies the root target and loads the application.

src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

The application entry point. This is the first component to get loaded. The application is defined here.

src/App.js
export default function App() {
return (
<div className="App">Hello, World!</div>
);
}

The Basics

React components are simply stand-ins for HTML elements, are written in JSX, and follow a similar syntax.

<div>Hello, World!</div>
<p>How are you doing?</p>
<span>Would you like to go on an adventure?</span>

There are a few notable differences.

Closing tags

They aren’t essential for elements that do not have children elements, but all elements must be closed. Either by using a closing tag, like

<div></div>

or self-closing slash

<img src="" />

Attributes

Attributes in React are called Props. Props in React follow the camel case convention, and the values passed are objects. The props must be contained within {...}.

The exception to this is strings, which can be passed as is.

<button id="test-button" onClick={...}>Click Me!</button>

Specific to React, the class attribute is switched with the className attribute

<div className="container">
...
</div>

Functions as Props

A lot of components in react take functions as props. The best example of this is button.

function handleClick() {
window.alert('Button clicked!');
}
<button onClick={handleClick}>Click Me!</button>

Functions can either passed by reference (like above) or as in-line anonymous functions:

<button onClick={() => {
window.alert('Button clicked!');
}}>Click Me!</button>

Fragments

React also lets you define an empty JSX element that groups children elements without adding a separate node to the DOM.

<Fragment>
<div>This is child 1</div>
<button>CliCkkk</button>
</Fragment>

You can also use the <>...</> shorthand:

<>
<div>This is child 1</div>
<button>CliCkkk</button>
</>

Components

Components can be thought of as the building blocks of react. These are isolated islands of UI and they define what actually gets rendered on-screen.

Defining Components

You can define a component by declaring a function that returns a single JSX element (ReactNode).

The element doesn’t have to be an HTML element, but can also be either a react component, or a fragment (more on that below).

src/components/BasicComponent.jsx
export const BasicComponent = () => {
return (
<div>
<p>This is a basic component.</p>
</div>
)
}

Lists of Components

Displaying a list of values can be done using the map function. In this, the function inside map must return a JSX element to be valid.

When using a list, remember to include a unique ‘key’ prop for that list. This helps react track changes in the list, such as additions, removals, or reordering of elements.

src/components/Friends.jsx
export const ListComponent = () => {
const items = [
'Item 1',
'Item 2',
'Item 3',
'Item 4'
];
return (
<ul>
{
items.map((item, index) => <li key={index}>{item}</li>)
}
</ul>
)
}

Conditional Rendering

To render an element conditionally, you can use the && syntax.

src/components/BasicConditional.jsx
export const BasicConditional = () => {
const isTrue = false;
return (
<div className="adventure-status">
{
isTrue &&
<p>This only renders when `isTrue` is true.</p>
}
</div>
)
}

If you want to treat it like an if-else block, you can use the ternary operator.
<condition> ? <true> : <false>

src/components/TernaryConditional.jsx
export const TernaryConditional = () => {
const isTrue = true;
return (
<div className="adventure-status">
{
isTrue
? <p>This renders when `isTrue` is true</p>
: <p>This, when it's false.</p>
}
</div>
)
}

Passing Props

You can define the props to be passed in to a React component through it’s function declaration. All props are passed in the props parameter.

src/components/PassedProps.jsx
export const PassedProps = (props) => {
return (
<div>
<h1>{props.title}</h1>
<p>{props.description}</p>
<img src={props.img} alt={props.alt} />
</div>
)
}

The values for the props can then be passed in to your custom element by passing them like HTML Attributes like so:

src/App.js
import PassedProps from "./components/PassedProps"
export default function App() {
return (
<div className="App">
<PassedProps
title="Article Title"
description="Just the most rivetting description."
img="/assets/pikachu-face.jpg"
alt="Never gonna give you up"
/>
</div>
);
}

Passing Children

To nest children inside a react component, you can use the { children } property on props.

export const ParentComponent = (props) => {
return (
<div>{props.children}</div>
)
}

Hooks

Hooks are special functions that let you ‘hook’ into reactive states and lifecycle functions from within function components. This is a fancy way of saying that hooks let you abstract reactive logic away from your components.

The Rules

There’s two things you need to keep in mind when using hooks. You can:

  1. Only call hooks at the top level
  2. Only call hooks from React functions

That means no calling hooks from inside loops or nested functions.

Common Hooks

useState

To handle internal state, a react function can use the useState hook. This creates a reactive value that re-renders the component when that value changes.

src/components/UsingState.jsx
export const UsingState = () => {
const [counter, setCounter] = useState(100);
return (
<div>
<p>{counter}</p>
<Button onPress={() => setCounter(counter - 1)}>Yoink!</Button>
</div>
)
}

useEffect

When you want to react (no pun intended) to a state change, you can use the useEffect hook.

This hook also works as a lifecycle function, where it is called when this element

  1. Enters the DOM
  2. Exits the DOM
  3. Re-renders

An example of lifecycle reactivity:

src/components/Lifecycle.tsx
export const Lifecycle = () => {
useEffect(() => {
console.log('Entering')
return () => console.log('Exiting')
})
return (<h1>Lifecycle</h1>)
}

src/App.js
export default function App() {
const [show, setShow] = useState(false)
return (
<div className="App">
<button onClick={() => setShow(!show)}>Toggle</button>
{ show && <Lifecycle /> }
</div>
);
}

Here, the component Reacting logs ‘Entering’ and ‘Exiting’ in accordance with it entering/exiting the dom.

You can also define constraints around when a useEffect function will be triggered based on a list of reactive values.

src/components/Reactive.jsx
export const Reactive = () => {
const [counter, setCounter] = useState(100);
useEffect(() => {
console.log(`Count is down to: ${counter}`)
}, [counter])
return (
<div>
<p>{counter}</p>
<Button onPress={() => setCounter(counter - 1)}>Yoink!</Button>
</div>
)
}

useRef

To reference and/or manipulate DOM elements, you can use the use the useRef hook.

src/components/Referencing.tsx
export const Referencing = () => {
const inputRef = useRef(null);
function handleClick() {
if (inputRef.current) inputRef.current.focus();
}
return (
<>
<input type="text" ref={inputRef} />
<button onClick={handleClick}>Focus Input</button>
</>
)
}

useRef also allows you to store state without triggering a re-render on change.

src/components/NoRerender.jsx
export const NoRerender = () => {
const [counter, setCounter] = useState(0);
const prevCount = useRef(0);
function addOne() {
prevCount.current = counter;
setCounter(counter + 1);
}
return (
<div>
<p>Counter: {counter}</p>
<p>Previous: {prevCount.current}</p>
<button onClick={addOne}>+1</button>
</div>
)
}

useContext

While passing props to components can work, it becomes tedious and difficult to manage when you need to pass some state down to a deeply nested component, or if you need to have multiple components access the same state. This is where contexts come in.

Contexts let a parent - even a distant one - provide some data to the entire tree inside it

Some common use cases can be passing the theme of the application to all it’s components, so it can react to light mode-dark mode switches.

Using a context happens in three stages:

  1. Declaring the context
src/contexts/ThemeContext.jsx
export const ThemeContext = creatContext('dark');
  1. Providing the context
src/App.js
export default function App({children}) {
const [theme, setTheme] = useState('dark')
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
)
}
  1. Using the context
src/components/Switcher.jsx
export default const Switcher = ({children}) => {
const theme = useContext(ThemeContext)
return (
<div className={theme == 'light' ? 'light-colors' : 'dark-colors'}>
{children}
</div>
)
}

Custom Hooks

You typically want to create custom hooks when you see repetitive logic being used across components.

The hook must start with the ‘use’ keyword for it to be considered valid.

src/components/useOrientation.jsx
export const useOrientation = () => {
const [orientation, setOrientation] = useState('portrait');
function checkOrientation() {
return window.innerHeight > window.innerWidth ? 'portrait' : 'landscape'
}
useEffect(() => {
window.addEventListener('resize', checkOrientation);
return () => window.removeEventListener('resize', checkOrientation);
})
}

Conclusion

While this should be enough to get you started. I highly recommend checking out the official docs for react to gain a deeper understanding of the framework!