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 server

  • npm 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 scoped

  • let is a block scoped variable

  • const 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 of onclick

  • onClick={shoot} instead of onClick="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 and Routes

  • 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 components

  • This 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/>
    </>
    );
};