React¶
As explained by
React
creates a VIRTUAL DOM in memory
only changes what needs to be changed.
Basics¶
CLI
npx create-react-app my-react-app
npm start
start development, hot load servernpm install <packagename>
npm uinstall <packagename>
import React from 'react';
import ReactDOM from 'react-dom/client';
function Hello(props) {
return <h1>Hello World!</h1>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Hello />);
Components¶
React relys on components, e.g. the App
component from the npx create-react-app command.
src/App.js
function App() {
return (
<div className="App">
<h1>Hello World!</h1>
</div>
);
}
export default App;
react heavily relys heavily on ES6
ES6 - ECMAScript 6. since 2015¶
Classes¶
class Car {
constructor(name) {
this.brand = name;
}
present() {
return 'I have a ' + this.brand;
}
}
class Model extends Car {
constructor(name, mod) {
super(name);
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model
}
}
const mycar = new Model("Ford", "Mustang");
mycar.show();
Arrow Functions¶
Shorter function syntax.
hello = function(){
return "Hello World";
}
becomes
hello = () =>{
return "Hello World";
}
becomes
hello = () => "Hello World!";
(but why though 🤷♂️)
We can also use parameters
hello = (val) => "Hello " + val;
and remove parentheses
hello = val => "Hello " + val;
Variables¶
var
global scoped, function scopedlet
is a block scoped variableconst
block scoped
Array Methods¶
.map
.find
.filter
.from
.of
prototype.copyWithin
prototype.find
prototype.findIndex
prototype.entries
prototype.keys
prototype.values
prototype.fill
https://www.javatpoint.com/es6-array-methods
Destructing¶
const vehicles = ['mustang', 'f-150', 'expedition'];
const [car, truck, suv] = vehicles;
const myArray = ['apple', 'banana', 'orange'];
const myList = myArray.map((item) => <p>{item}</p>)
Modules¶
export
You can export a function or variable from any file.named exports
export const name = "Jesse";
const name = "Jesse";
const age = 40;
export {name, age}
default exports
You can have one default export in a file.
const message = () => {
// ...
}
export default message;
import
imports from named exports
import {name, age} from "./persons.js";
imports from default exports
import message from "./message.js";
Ternary Operator¶
authenticated ? renderApp(): renderLogin();
Spread Operator¶
...
quickly copy all or part of an exisitng array into another array
const numbersOne = [1, 2, 3];
const numbersTwo = [4, 5, 6];
const numbersCombined = [...numbersOne, ...numbersTwo];
React Render HTML¶
Render on any id-able component
ReactDOM.render(<p>Hallo</p>, document.getElementById('sandy'));
JSX¶
JSX stands for JavaScript XML.
JSX allows us to write HTML in React.
JSX makes it easier to write and add HTML in React.
const myElement = <h1>I Love JSX!</h1>;
No JSX
const myElement = React.createElement('h1', {}, 'I do not use JSX!');
Expressions
const myElement = <h1>React is {5 + 5} times better with JSX</h1>;
Elements must be closed
const myElement = <input type="text" />;
Class = className
const myElement = <h1 className="myclass">Hello World</h1>;
Components¶
class component
derived from
React.Component
render()
method
class Car extends React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
function component
function Car() {
return <h2>Hi, I am a Car!</h2>;
}
rendering a component
root.render(<Car />);
props
function Car(props) {
return <h2>I am a {props.color} Car!</h2>;
}
//...
root.render(<Car color="red"/>);
nested components are the driver of everythin
Class components¶
Mostly outdated but the forerunner of function components and more versatile
Events¶
onClick
instead ofonclick
onClick={shoot}
instead ofonClick="shoot()"
.Parameters
function Football() {
const shoot = (a) => {
alert(a);
}
return (
<button onClick={() => shoot("Goal!")}>Take the shot!</button>
);
}
Event object
return (
<button onClick={(event) => shoot("Goal!", event)}>Take the shot!</button>
);
Conditional rendering¶
function Goal(props) {
const isGoal = props.isGoal;
if (isGoal) {
return <MadeGoal/>;
}
return <MissedGoal/>;
}
{cars.length > 0 && <RenderThis/>}
condition ? true : false
{ isGoal ? <MadeGoal/> : <MissedGoal/> }
Lists¶
{cars.map((car) => <Car brand={car} />)}
Keys
Keys need to be unique to each sibling. But they can be duplicated globally.
parameters gathered in one prop
function Car(props) {
return <li>I am a { props.brand }</li>;
}
// ...
const cars = [
{id: 1, brand: 'Ford'},
{id: 2, brand: 'BMW'},
{id: 3, brand: 'Audi'}
];
//...
{cars.map((car) => <Car key={car.id} brand={car.brand} />)}
Forms¶
We can use the useState Hook to keep track of each inputs value and provide a “single source of truth” for the entire application.
import { useState } from 'react';
// ...
const [name, setName] = useState("");
//...
<input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
One
userState
onChange
-handler can be used to handle multiple inputs
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs(values => ({...values, [name]: value}))
}
The form event handling can be done in react
<form onSubmit={handleSubmit}>
React router¶
npm i -D react-router-dom
Create several pages
Routes are wrapped in
BrowserRouter
andRoutes
Route
can be nested
import Layout from "./pages/Layout";
import Home from "./pages/Home";
import Blogs from "./pages/Blogs";
import Contact from "./pages/Contact";
import NoPage from "./pages/NoPage";
// ...
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="blogs" element={<Blogs />} />
<Route path="contact" element={<Contact />} />
<Route path="*" element={<NoPage />} />
</Route>
</Routes>
</BrowserRouter>
The “layout route” is a shared component that inserts common content on all pages, such as a navigation menu.
The Layout component has
<Outlet>
and<Link>
elements.The
<Outlet>
renders the current route selected.<Link>
is used to set the URL and keep track of browsing history.
<Link to="/blogs">Blogs</Link>
CSS¶
escaped curly braces
{{}}
<h1 style={{color: "red"}}>Hello Style!</h1>
camelCased properties
<h1 style={{backgroundColor: "lightblue"}}>Hello Style!</h1>
module files
The CSS inside a module is available only for the component that imported it, and you do not have to worry about name conflicts
import styles from './my-style.module.css';
SASS¶
npm i sass
React Hooks¶
You must import Hooks from react.
Hooks can only be called inside React function components.
Hooks can only be called at the top level of a component.
Hooks cannot be conditional
useState¶
useState allows us to track state in a function component
import { useState } from "react";`
// ...
const [color, setColor] = useState("");
The first value, color, is our current state.
The second value, setColor, is the function that is used to update our state.
read state
const [color, setColor] = useState("red");
write state
onClick={() => setColor("blue")}
updating objects and arrays
const updateColor = () => {
setCar(previousState => {
return { ...previousState, color: "blue" }
});
}
useEffect¶
useEffect
allows you to perform side effects in your components.useEffect
accepts two arguments. The second argument is optional.
useEffect(<function>, <dependency>)
//Runs on every render
useEffect(() => {
});
//Runs only on the first render
useEffect(() => {
}, []);
//Runs on the first render
useEffect(() => {
//And any time any dependency value changes
}, [prop, state]);
useContext¶
useContext
allows us to share state between deeply nested componentsThis can be used to circumvent passing multiple arguments
useRef¶
useRef
allows you to persist values between renders.
useReducer¶
useReducer
allows for custom state logic.
useCallback¶
useCallback
returns a memoized callback function.
useMemo¶
useMemo
returns a memoized value.
Custom hooks¶
React and TypeScript¶
npx create-react-app Name --template typescript
Provide
Function Components
FCs
import React from "react";
export const TextField: React.FC<{text: String}> = () =>{
return (
<>
<TextField/>
</>
);
}
more readable
import React from "react";
interface Props {
text: string;
ok: boolean;
i: number;
fn: () => void;
}
export const TextField: React.FC<Props> = () =>{
return (
<>
<input/>
</>
);
};