React
date
Nov 30, 2022
type
KnowledgeBase
year
slug
react
status
Published
tags
React
JavaScript
summary
All about React and React Router
React makes it painless to create interactive UIs on the web.
Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.
Once you know your way around React you might want to step up to Next.js
Set up
Option A: Create a starter project with npx create-react-app
Set up a project with
npx create-react-app my-app
(https://reactjs.org/docs/create-a-new-react-app.html)Or if you prefer yarn, then
yarn create react-app my-app

This creates a basic React project from the default template with everything you need.
There are many other templates as well.
- Minimal (even more minimal)
npx create-react-app my-app --template minimal
- Minimal with Typescript:
npx create-react-app my-app --template minimal-typescript
- Template with React and Redux and Typescript:
npx create-react-app my-app --template redux-typescript
- Popular React boilerplate:
npx create-react-app my-app --template rb
Or maybe use this cleaned up version below:
Option B: Use this cleaned up starter project
(from the react course on Udemy)
- run
npm install
- open folder in VSCode or WebStorm
- Terminal > New Terminal (VSCode) or click on the Terminal tab on the bottom (WebStorm)
npm start
Â
What this contains is basically this:
- files in the public folder will be served directly via the web server
index.html
is an HTML5 file with a<div id="root"></div>
in the body. React will replace this with whatever content you make it render!
- The src folder contains everything you want to bundle as a single package. Javascript, CSS, icons, JSON files, etc.
- Bundling starts at
index.js
. - The main application file is usually called
App.js
package.json
is the main configuration file for the project, required by npm
index.html:
index.js:
App.js:
Option Nope: Minimal React without JSX - stupid idea. WHY?
This is stupid. Why wouldnât we use JSX?! But oh wellâŚ
Put it in a folder somewhere and run a simple web server from that folder. There are many options:
- run
npx serve
(node)
- run
npx http-server
(node)
- run
python -m SimpleHTTPServer 3000
(Python 2)
- run
python -m http.server 3000
(Python 3)
- run
php -S localhots:3000
(PHP)
JSX
JSX Helps you write readable React code by inlining components so that they look like html-tags!
Full example of a React component:
This is a function component. And thatâs the way to go. Donât use class components anymore
Custom Components
Create component, export component, import component, use it.
Component name has to be uppercase! Thatâs als how you distinguish between built-in html components and React components:
<CustomReactComponent>
vs <html>
Components can only return one single element, so if you need to return multiple you can wrap them in a
<div>
or Reactâs <Fragment>
(in newer versions a Fragment can just be <>
</>
)
Variables go in curly braces:
You can also call functions in curly braces, etc.:
Custom components can use properties (attributes) too:
And then use just it like you would in HTML:
The spread operator (
âŚ
) is useful if you want to render all the propertiesâŚ
How to deal with child nodes:
Use (abuse? đ) how JS handles true/false by making our logical expressions return false or a react element (if isVerified is true it adds the Checkmark, otherwise it wonât):
Instead of a switch statement we can use an object with properties for the different cases resolving the different outcomes (the || makes sure any unknown cases show as deleted):
Show a list of options by mapping from a list of items
Fragments
<></>
are empty React elements that result in no HTML. Their only purpose is to group multiple other elements together. (You might need this, because a component can only return a single element, so if you want multiple, wrap them in a FragmentâŚ)
Before React 16.2 you actually had to use
<Fragment></Fragment>
Send tags through props via mixed arrays:
CSS
JSX uses camelCase where CSS uses hyphens
font-size
â fontSize
Where in HTML/CSS you would set
in JSX you have to do
example of applying multiple styles:
You can also put the styles into a variable and then apply it:
Or add css to a component by importing it at the top
in JSX, use
className
instead of class
!SASS
SASSAdd it to project
$ npm i -g sass
Then you can simply import sass files into components and it will work!
import './Countdown.scss';
Events
<button onClick={console.log('Click');}>
In the example below, notice how we donât have
()
when referring to clickHandler
! If we had braces it would execute during rendering, not when clicked!In the following example, note how the 3rd button fails and executes during rendering and not when clicked.
But if we canât have
()
, then how can we send along parameters?! Turn it into an arrow function like this: (Note how the 3rd button also works on click now that we turned it into an arrow function!)
Gotchas
What things render as
Type | Output |
âstringâ | "stringâ |
"â | "â |
3.4 | "3.4â |
0 | "0â |
NaN | "NaNâ |
Number.POSITIVE_INFINITY | "Infinityâ |
Number.NEGATIVE_INFINITY | "-Infinityâ |
true | "trueâ |
false | "â |
undefined | ââ |
null | ââ |
Notably only 4 of the things that are falsy render as empty strings, while 0 renders as â0â and NaN as âNaNâ. This could lead to issues when you do stuff like this:
so you have to do this instead:
Multi-word Attributes
Multi-word attributes also switch to camelCase in JSX.
clip-path
â clipPath
, fill-opacity
â fillOpacity
, etc.And confusingly even multi-word attributes that are all lowercase in HTML, switch to camelCase:
autoplay
â autoPlay
, allowfullscreen
â allowFullscreen
, or input fieldâs maxlength
â maxLength
Reserved Names
class and for are reserved words in JavaScript, so in JSX you have to use className and htmlFor instead.
If you want to assign a CSS class:
If you need to create a label for a form element:
Boolean Attribute Values
The attribute value must be set as a JavaScript expression (inside
{}
) and not as a string!
If you omit a value after the property, React will set the value to true
Functional components
As mentioned at the top: Use only functional components - they are the way forward. Below weâll look at class components đˇÂ and why we hate them now.
Example:
This HTML menu

Â
built with class components looked like this:
But built with functional components it looks like this! Much more compact and clean!
And if weâre extra cool we can even turn them into Arrow Function Components! (You know you want toâŚ)
We simply create a function and return JSX, thatâs it! Functional component!
If we need access to properties, we get it through the single argument passed to the function, which is a frozen object of properties.
Any value that can be executed as a function, that returns JSX, can be used as a component! You can even define them inline in another component:
we could even shorten it further using implicit return:
Destructuring Properties
Destructuring allows us to pick out the things we need from the single argument that is passed to our functional component:
We can also use this in normal functions btw:
Default Values
We can add default values by adding them to the function definition like this:
If we have some props we just want to pass through we can do this via Rest operator:
Hooks
Hooks are an umbrella term for a new kind of special function that âhooksâ from your component into the React core machinery.
Functions that start with the word
use*
are hooks.When you use a hook in a component, you must always use that hook. And you must use the exact same hooks in the exact same order every time you render the component.
So if you use a hook you must always call it, you canât wrap it in an
if
or exit out early - the hook must always be called!There are 15 types of build-in hooks in React 18:
- Stateful hooks (making components and applications stateful):
useState
,useReducer
,useRef
,useContext
,useDeferredValue
,useTransition
- Effect hooks (running effects inside components):
useEffect
,useLayoutEffect
- Memoization hooks (performance optimization via avoiding re-calculating values):
useMemo
,useCallback
,useId
- Library hooks (only really needed in larger projects):
useDebugValue
,useImperativeHandle
,useInsertionEffect
,useSyncExternalStore
State
State allows us to change values and have the relevant component redraw without reloading the page.
Weâre only dealing with state for functional components here. Class-based components work differently - see here
In general, any state used in a web application belongs to one of three categories:
- Application data (data the user is working on)
- UI state (which tab is active, whether a panel is collapsed or not, etc.)
- Form data
Â
Very simple API which consists of a single function,Â
useState
(a hook!)- takes an initial value
- returns the current state and an update function
Simplest possible example: A counter. When the user clicks a button, we increment the counter and react updates the rendered element.
Note how
counter
is a const
ant value, so calling setCounter
doesnât update it immediately! You canât call setCounter
and immediately continue as the value in counter
will not update until after the next render! â Instead use an effect that reacts to counter
changing!More complex example where weâre setting a function instead of a value!
Previous Value
The setState function conveniently gives you the previous state:
State scope
State that spans multiple components. What if we want to access the value in one component, but update it in another?
In the code below, notice how the
TodoApplication
feeds the update function setHideDone
up into the FilterButton
. State is stored in TodoApplication and passed around to other components where applicable to render the result we need.
useRef - remember a value without re-rendering
Like with
useState
we can persist the state, but useRef
doesnât cause a re-render of the component! Just set the new value via .current
useRef - to get references to DOM elements
We will also use
useRef
to get references to DOM elements. Below we create a variable
ref
with useRef()
, then put it into the input tag and use the useEffect
hook (configured to only trigger on mount) to focus that element. Specifically we auto-focus an input field when a component is mounted:
Or another example where we use ref to figure out which of two buttons was pressed. Both buttons call the same
onClick
function and it uses the ref increment.current
to compare against the evt.target
:
useContext
similar to
useState
, but useContext
works in a store in a parent component somewhere up the component tree.Context wraps a number of components with a value that all descendant components can access without going through properties at all.
Occasionally you find yourself passing properties through multiple components just to reach the place where you actually want to display it. (This is called prop drilling) This can become problematic in larger code bases. With Context you donât have to do thatâŚ
You need 2 parts:
- Provider - contains the value you want to access, set up via
createContext(defaultValue)
and then fill via<XYZContext.Provider value={value}>
- Consumer - in each component that wants to use the value
Example:
Note how we use state to set the name and how that basically re-renders the entire site whenever we change it. To prevent that from happening with Memoization. We wrap some things in
memo()
and weâre good: const Header = memo(Header() { ... } );
When you consume a context, you will get the value provided by the nearest provider going up the document. If no provider exists above the consumer, you will get the default value as defined when the context we created.
Ok, so a context can hold different values in different places. Sounds like a bug, but if youâre adventurous you can use it as a feature:
Example with context having different values in different places (borderWidth)
You can put complex objects and even functions into context!
The problem with this is that everything consuming anything from inside the context will update if something updates in there, even if itâs something that your Component doesnât even use. (will be addressed in future version of React or can be done via context-selector now)
Example with context as a delivery mechanism for stateful value and setters
Switch between dark and light mode

useTransition
New in React 18: Concurrency concept.
useTransition
can be used to tell React that certain state updates have lower priority. When calling useTransition
you get back an array with two elements: an isPending
boolean value (tells you if the update is still pending) and a startTransition()
function that can be wrapped around a state update to tell React that it is a low priority update.
Note how
setFilterTerm()
is wrapped by startTransition()
- without the use of useTransition()
the app could get unresponsive.useDeferredValue
If you canât use
useTransition()
because the code that should be wrapped is outside your control, you can use useDeferredValue()
. You donât wrap the state-updating code, instead you wrap the value thatâs in the end generated or changed because of the state update.
React will perform other state or UI updates with a higher priority than updates related to the
products
value.useReducer
The term reducer is used to refer to the function or a set of functions that converts the current state into a new state based on a given action. In React we expect reducers to be pure, deterministic and side-effect free as well.
You invoke
dispatch
with an action object, that is then passed to the reducer
along with the old state, and the reducer
is expected to return the new state.
Flow of data is similar to a
useState
hook- starts with an initial value
- then updates as the application progresses
BUT the way that you update the internal state is more complex, in that you "reduce" the new state from the old one using functions and actions.

dispatch
 works as our enhanced setter function, which allows us to not set the value directly, but rather instruct the reducer function on how to set the value.
Alternative to
useReducer
: The external library use-reduction
provides a much cleaner interface, namely useReduction
Effects
Effects are functions that run inside a component under certain circumstances. This can be done with an effect hook called
useEffect
An effect in a
useEffect
hook is triggered when either value in a set of dependencies changes.An effect can define a cleanup function that runs either before the effect is triggered again or if the component unmounts.
As you see above, every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. Theyâre part of the same effect!
But it doesnât have to do cleanup. Hereâs an example without:
We can also do just the cleanup
We can pass in a second argument to
useEffect
that allows us to restrict when the effect runs. If we give it a variable it will only run the effect if that variable updates!
LayoutEffect
If we use
useLayoutEffect
instead of useEffect
we can run an effect after React generates the HTML, but before the browser updates the UI and displays it. (Only needed in special cases)
Dependency Arrays
Used by
useEffect
, useCallback
, useMemo
and useLayoutEffect
.3 ways - very different outcomes! Note how a missing dependency array does pretty much the opposite of an empty dependency array!
- donât specify an array at all - hook should be triggered on every render
- specify an empty array - hook will only trigger on mount and never again
- specify a non-empty array - hook will trigger if any of the given values in the array change on a render
Events
Events are the way users interact with a JavaScript web application.
To handle an event, assign any function to the value of the event on an object that might dispatch such an event. The event handler function will be called with a single argument: an event object (you can ignore it if you donât care)
Another example:
You can only use React to listen for events that are actually supported by React.
Supported Events
Clipboard events -
onCopy
, onCut
, onPaste
Composition events -
onCompositionEnd
, onCompositionStart
, onCompositionUpdate
Keyboard events -
onKeyDown
, onKeyPress
, onKeyUp
Focus events -
onFocus
, onBlur
Form events -
onChange
, onInput
, onInvalid
, onReset
, onSubmit
Generic events -
onError
, onLoad
Mouse events -
onClick
, onContextMenu
, onDoubleClick
, onDrag
, onDragEnd
, onDragEnter
, onDragExit
, onDragLeave
, onDragOver
, onDragStart
, onDrop
, onMouseDown
, onMouseEnter
, onMouseLeave
, onMouseMove
, onMouseOut
, onMouseOver
, onMouseUp
Pointer events -
onPointerDown
, onPointerMove
, onPointerUp
, onPointerCancel
, onGotPointerCapture
, onLostPointerCapture
, onPointerEnter
, onPointerLeave
, onPointerOver
, onPointerOut
Selection events -
onSelect
Touch events -
onTouchCancel
, onTouchEnd
, onTouchMove
, onTouchStart
UI events -
onScroll
Wheel events -
onWheel
Media events -
onAbort
, onCanPlay
, onCanPlayThrough
, onDurationChange
, onEmptied
, onEncrypted
, onEnded
, onError
, onLoadedData
, onLoadedMetadata
, onLoadStart
, onPause
, onPlay
, onPlaying
, onProgress
, onRateChange
, onSeeked
, onStalled
, onSuspend
, onTimeUpdate
, onVolumeChange
, onWaiting
Image events -
onLoad
, onError
Animation events -
onAnimationStart
, onAnimationEnd
, onAnimationIteration
Transition events -
onTransitionEnd
Other events -
onToggle
Â
Custom Hooks
The definition of a custom hook, is a function that uses a hook. Simple as that.
For example:
Than use like this:
Another example that handles form input
then use like this:
Get more hooks here:
Forms
Controlled inputs - React manages whatâs in each input via
value
and onChange
Uncontrolled inputs - React doesnât care about anything and you only look at the input once the user submits. Then you access the inputs via evt.target.elements.*
in the onSubmit
event.This is how you handle controlled inputs:
We specify both theÂ
value
 and the onChange
 properties for our inputs. This is required to make a controlled input.If you set the value directly in React, you must also listen for the change event and update the value and this makes your input controlled.
You can use this to filter input:
or to apply a mask:
Uncontrolled Inputs:
Example: Controlled via Uncontrolled Submit via POST
With controlled inputs:
Same thing with uncontrolled inputs: (actually simpler in this case!)
File Inputs
File Inputs can only be uncontrolled.
Â
Next.js example (Move?)
Optimising performance - useMemo
Minimize re-rendering! JavaScript tries to run at about 60 fps (16ms per frame) Each time React renders one or more components it counts as one frame. If the entire React render takes more than 16ms, your browser will start to treat your script as âslowâ and start dropping frames. If you have lots of animations, your users will noticeâŚ
Response time matters - if a user interface doesnât update within 0.1 seconds, it does not seem instantaneous to the user. Weâre already losing 16ms because due to the new state of component rendering only on the next frame, letâs not waste the rest of the time we haveâŚ
Memoization is the concept of remembering the last input and output of a pure function. If the function is invoked again with those same inputs, we just return the same value again rather than call the function again. - This only makes sense for pure functions whose return value depends solely on their inputs! Similar to caching, but usually only remembers the last value.
This is a shitty example that doesnât work. Figure this out laterâŚ
You can memoize bits of React applications in three ways:
- memoize an entire component
- memoize a bit of JSX
- memoize a property to be passed to a component
Memoize a component:
use
useMemo
to mamoize any value between rendersuseCallback
is basically the same as `const useCallback = (fn, deps) => useMemo(() => fn, deps);
React Developer Tools Browser Plugin
Adds a few things to the Inspect panel. (Which you should already be using for the console, etc.)


Components lets you inspect react components!
Profiler shows you how long everything takes, etc.
And this setting is also convenient: highlights each component that re-renders:
Â

Common Errors
Changing uncontrolled input to be controlled
Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
Happens in this case:
Not obvious, but starting the state out as
undefined
is the issue. Do this instead:
Other stuff
props.children gives you all the child-elements
Custom elements wonât take on className automatically (
<Card className=âblahâ>
does nothing), youâll have to apply it yourself (props.className) in the componentÂ
function
Card(props) {}
is the same as const Card = (props) => {}
Â
Â
Â
Â