Don’t Forget React
The Virtual DOM
The “engine” of React, that updates the Real DOM when needed.
The “Virtual DOM” checks the old “Virtual DOM” – Changing the virtual
DOM is much faster, because it’s just a JavaScript object.
Then, depending on what changed, it will update the real DOM!
WHAT
OLD VIRTUAL DOM CHANGED? NEW VIRTUAL DOM
<body>
<div> <div>
<div> <h3> <ol>
<h1> <p> <li> <li>
this part
Update this:
DOM HTML
[ ]
We no longer use the
document. methods
REACT directly
React does that for us.
JSX – the special language of React
Almost like HTML, with a few key differences
In HTML In REACT (note the closing tag)
<input type="text" > <input type="text" />
<img src="person.png" <img src="person.png"
alt="person" > alt="person" />
All tags must now have a (self) closing tag (for example, input and img)
In HTML In REACT (note the closing tag)
<p class=”primary-text”></p> <p className="primary-text">
</p>
<p style=”color:white”></p>
<p style={{color: "white" }}>
</p>
Some properties change, for example class becomes className=, and style= now
takes a javaScript object instead of a string.
function MyComponent() {
return <p>This is JSX!</ p>
}
Using JSX, we can create “custom” elements, with their own structure, properties,
logic, and styling. In React these are known as components. Components must
return JSX.
function MyComponent() {
return (
<form onSubmit={...} >
<input type=”text” onChange={...} />
<button onClick={...} >Click me! </button>
<input type=”submit” />
</form>
)
}
camelCase “Handler” properties onClick, onChange, and onSubmit replace
addEventListener for user events in JSX.
This doesn’t work right This does (note anonymous function
<button <button
onClick={console.log onClick={() => console.log
("clicked")} ("clicked")}
> >
Click me! Click me!
</button> </button>
They take a function as a value, Don’t Call this Function! Use an anonymous /
wrapper function if necessary.
<input
type="text"
onChange={e => console.log
(e.target.value)} /> logs everytime we type
The “event object” (e) will contain the data you need for “onChange” in a text input, ex:
<button
onClick={ ( ) => setClicked(true) }
>
Click me sets state variable on click
</button>
You don’t always NEED the event object, though.
Components
Think of Components as “Custom JSX Elements” that we can define, and then use one
or more times. Ultimately, the components are just like variables which will be
converted to HTML.
JS MyComponent.js
export default function MyComponent() {
return <p>This is JSX!</ p>
}
Defining a component
JS App.js
import MyComponent from "./MyComponent";
export default function App() {
return (
<>
<MyComponent />
<MyComponent />
<MyComponent />
</>
);
}
Using it inside a second App Component
<> Index.html
<p>This is JSX!</ p>
<p>This is JSX!</ p>
<p>This is JSX!</ p>
HTML output will be
How big should components be?
There’s no hard rule a couple of rules of thumb I use:
Will I use this Component more than once?
[ ]
To see a full example
Does it make sense to logically group this of a component, go
section together and name it something like to the last page!
“TopNavBar” or “Thumbnail”
The Component Tree, Importing and Exporting
The convention is 1 component per file We MUST export components to use them
in other files
export default function MyComponent( ) { … }
Then we can import into another file.
import MyComponent from "./MyComponent"; [ ]
(the extension .js,
or .jsx is optional
when importing)
export default function AllMyComponents ( ) {
return (
<>
<MyComponent />
<MyComponent />
<MyComponent />
</>
)
}
As above, our components will go inside one another, and we can use
them multiple times.
So our component tree ends up looking like this:
<All MyComponents/>
<All MyComponents/> <All MyComponents/> <All MyComponents/>
How to Install React & NPM
We can install React with NPM and NodeJS locally. We will need the React library,
and its dependencies. It’s generally recommended to use a framework like
Create-React-App, Vite, or NextJS rather than starting from zero. This will give
you boilerplate and save you time.
CREATE
APP
npm install react
You can install additional libraries and dependencies, like React Router or
Material UI, with “npm install”
{ } package.json
"dependencies": {
"react": "18.0.0",
"react-dom": "18.0.0",
"react-scripts": "4.0.0"
},
Then, these will be added node modules folder, which contains all your library code.
(You don’t commit this to GitHub)
These will be added to package.json, which is the “assembly manual” for your app...
Transpiling
Browsers can’t run React code, so it must be TRANS-piled to vanilla JavaScript,
HTML and CSS. There are libraries that do this for us. Babel and Webpack.
Transpiling takes all our .JSX or .JS files (React can be written in both) and, by
default, puts them into a single large bundle.js file
App.js
Component1.js Bundle.js
Component2.js
And all our dependencies, into a vendor.js file.
Loading these big files over a network can really slow things down
Having one massive bundle.js will slow down our initial page load, however
bundlers have improved on this over time with things like:
Server Side Rendering Code Splitting Lazy Loading
This is important for larger apps...
And frameworks like Next JS will do this for us.
Props
The “arguments” of a component, they’re how we pass data from one component
to another.
<MyComponent name="Aaron" />
Think of them as “custom properties” – we send them with the “key=value” syntax
function MyComponent( props ) { Aaron prints
console.log(props.name);
…
}
And receive them with “props” object – so they can be accessed accordingly.
function MyComponent( { name } ) { Pull name value
… from props object
}
We can “destructure” them like so ...
function MyComponent( { name } ) {
return <p> Hello, { name } </ p>
}
And can use them accordingly ...
function AllMyComponents ( ) {
return (
<>
<MyComponent name="Aaron" />
<MyComponent name="Jack" />
<MyComponent name="Jan" />
</>
)
}
In the tree model, passing props might look like this ...
So our component tree ends up looking like this:
<All MyComponents/>
{name:”Aaron”} {name: “Jack”} {name:”Jan”}
MyComponent MyComponent MyComponent
<p> Hello, Aaron </ p>
<p> Hello, Jack </ p>
<p> Hello, Jan </ p>
And ultimately our HTML looks like this
State & State Hook
The “internal variables” of a component.
import React from 'react'
function MyComponent( ) {
[ ]
State must go INSIDE
const [myName, setMyName] =
our component,
React.useState("Aaron") conventionally, at the
... top.
}
We create them with useState hook, that takes an “initial value” returns an array of 2
myName will become the initial value “Aaron”
setMyName("Jack");
And we can update “myName” like so:
myName = "jack"; won’t work
But cannot assign anything directly to state (always use the setter function!)
const [myNames, setMyNames] =
React.useState(["Aaron"]); will NOT work
myNames.push("Jack") works, creates a copy
with array
setMyNames( [...myNames, " Jack"] ); spreading, adds “Jack”
at the end
Changing state will “update” the component it lives in, and all components
it’s passed to.
State is IMMUTABLE. If we want to update an array, we need to create a new copy
useEffect & React Life Cycle
When components get added to the page, they start the “component life cycle”
There are 3 key events:
Mount, Update, UnMount
MOUNT UPDATE UNMOUNT
Which we can attach behavior to each of these with useEffect.
useEffect, always runs when the component it’s inside is created
import React from 'react'
function MyComponent( ) { We can use promises
React.useEffect( ( ) => { inside.
fetch("https://myserverurl.com/
items/").then(...)
}, [ ])
…
}
We often useEffect to fetch some data once and only once, so we aren’t
unnecessarily bombarding our server.
It takes a function as the first argument, (this cannot be an async function)...
import React from 'react'
function MyComponent( ) { We can use promises
React.useEffect( ( ) => { inside.
fetch("https://myserverurl.com/
items/").then(...)
}, [ ])
…
}
We often useEffect to fetch some data once and only once, so we aren’t
unnecessarily bombarding our server.
It takes a function as the first argument, (this cannot be an async function)...
React.useEffect( ( ) => {
fetch("https://myserverurl.com/items/" When itemID changes,
+ itemID ) we run fetch again.
.then(...)
}, [ itemID ])
Optionally, an array of “dependencies” as the second argument
– These are the variables we can choose to “watch”, then if they change,
we run the function again
React.useEffect( ( ) => {
return ( ) => alert(" goodbye ! ") Only runs when
}, [ ]) component gets
removed from DOM
Optionally, we can also return a function which runs on “unmount”
Full React Component Example
This is an ES6 import of
import React from "react" the React library
import MyComponent from ". A relative import of a different
/MyComponent.js " component we wrote function
function MySecondComponent There is always a single
( props ) { “props” argument
const [myName, setMyName] = A state hook can save
React.useState("Aaron"); and update variables
React.useEffect( ( ) => { useEffect hook runs a
function we pass in
console.log("page loaded") At least once, when the
component “mounts”...
Optionally, again, when the variables
}, [ ]) we put in this array change
We must return JSX
return ( or we’ll get an error
We can group together JSX with
<> “Fragments” that create no HTML
<h1>
My name is {myName} {Curly brackets} Let us
write JavaScript inside JSX
</h1>
{ Inline logic works too
props.additionalText && <p> Here we only show a p
{props.additionalText}</p> if a prop exists
} We can switch from
JSX to JS and back.
Finally, we use the component
<MyComponent fruit="apple" /> we imported, and give it props
</>
);
}
We must export our component
export default MySecondComponent to use in other files!
Styling With React
In React, you can still use CSS files, for sure. But Styled
Components are more popular, especially with UI
[ ]
You want to keep
component libraries (see next section). styled components
free of data and state.
Styled Components
should be separate
to your components
with logic.
Styled Components mean all the styles are encapsulated
in your component, so you don’t have to mess around
with class names, multiple files, and generally makes
“everything you need” inside that component.
You can build styled components from the ground up, or
“compose” them in the same way you make CSS classes.
const Block = styled.div`
margin: 10px;
padding: 10px;
`;
For example, I can create a “Block” component that is
simply a “div” under the hood, that includes some
padding and margin.
const SmallBlock = styled(Block)({ const BigBlock = styled(Block)({
width: "100px", width: "500px",
}) })
And I can “extend” this block with more styles to create
“BigBlock” and “SmallBlock” styled components.
< SmallBlock />
FROM < div />
<div/>
TO < Block />
< BigBlock />
You’ll either use the “styled components” library or the
“styled” function of a UI Library like Material UI to do this.
Component Libraries
There are tons of component libraries, but the 2 most common are React Router,
and some form of UI Library
React Router
React Router enables us to do “Client Side Routing”, so we can have some
navigation in our React apps with multiple pages and paths that can be
observed in the URL bar.
index.html Faq.html
<h1>Hello there!</h1> <h1>FAQ</h1>
<a href=”faq.html”>Go to <a href=”index.html”>Go to
faq</a> home</a>
https://mywebsite.com/index https://mywebsite.com/faq
While in HTML, we’d need a different file and server request for each path...
App.js
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom ";
import Home from "./Home"
import Faq from "./Faq"
function App() {
return(
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="expenses" element={<Faq />} />
</Routes>
</BrowserRouter>
);
}
We can achieve the same result with React components by
1. wrapping our App in a “BrowserRouter”
2. creating <Routes> with the “path” and “element” parameters (setting each
path to a component)
Home.js Faq.js
import { import {
Link Link
} from "react-router-dom "; } from "react-router-dom ";
export default function Home() export default function Faq()
{ {
return( return(
<> <>
<h1>Hello there!</ h1> <h1>FAQ</h1>
<Link to="/faq"> <Link to="/">
Go to FAQ Go to Home
</Link> </Link>
</> </>
); );
} }
And linking to each path with a <Link>
UI Libraries
Let you use pre-built and styled Components in your apps,
that you can customize. This saves a massive amount of
[ ]
API is just shorthand
time. for “interface” or how
you interact with
You will have to have the docs for your library of choice something from the
outside, whether it’s
open to learn what components are available As well as a back end server,
their “APIs” – but in this context, the API is a component’s function, or React
props. component, you can
use this term.
Here are some examples from the Material UI Library
Simple Components Are Attractive Out of the Box
Complex Use Cases are Big Time Savers
You Can Customize Components Inline with sx
Or as above, write styled components
Visit
MUI.COM