React Quickstart Tutorial
Tags: javascript, react, webdev, tutorial
Published: 2022-06-26 23:58:22

React Quickstart Tutorial

## Contents

1. [Inspiration](#inspiration)
2. [Prerequisites](#prerequisites)
3. [Setup](#setup)
4. [The React Component](#the-react-component)
5. [Events](#events)
6. [State](#state)
7. [Hooks](#hooks)
8. [Routing](#routing)
9. [Extra Bits](#extra-bits)
10. [Sample Network Request and Render](#sample-network-request-and-render)



## Inspiration

I like using React, building reuseable blocks of code ( Components ) in your own style is quite a fun and stimulating experience. You may meet several react persons who use the framework but their code can be drastically different ( which can also be a very bad thing ), but I like to find my own way of doing things and react allows that. 



## Prerequisites

To start you'll need **Node**, **npm** and preferably **npx**, you can skip to the next section if you already have these installed ( [next section](#How-to-think-of-Webpack) )

### Installing Node
#### OPTION A: (Recommended NVM ( Node Version Manager)
It's generally recommended that you use nvm to install and manage versions of node. You can see instructions on how to install for you OS [here](https://github.com/nvm-sh/nvm#installing-and-updating). Definitely use the above link if you can, however if not you can try running these...
 
**install via curl**
`curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash`
**reload your terminal**
`source ~/.bashrc`
**check the install**
`nvm -v`
**use nvm to install a version of node** ( e.g. 16 )
`nvm install 16`
OR
**use nvm to install the latest version of node**
`nvm install node`

**use nvm to use a version of Node it installed** ( e.g. 16 )
`nvm use 16`

#### OPTION B: Direct Install
You can visit [here](https://nodejs.org/en/download/package-manager/) for installation instructions for your specific OS.

### npm and npx
npm and npx are usually installed alongside node, you can test with `npm --version` and `npx --version`.

Note: **Node**, **npm** and **npx** are all different things, **Node** is the execution environment ( basically the thing that runs the code ); **npm**, Node Package Manager, manages packages for **node**; **npx**, Node Package Execute, allows us to run installed **node** packages. The versions of each of these things are (mostly) independent and therefore when you run `npm --version` or `node --version` or `npx --version` DON'T EXPECT to see the same number.

Depending on which option you chose **npx** may not be installed, as such you can run the following: 

**install npx globally** ( DO NOT RUN IF YOU ALREADY HAVE npx INSTALLED, again check with `npx --version` )
`npm install -g npx`



## Setup 

### Files and Core Dependencies 

Let's create a folder `react_app`, and inside `react_app` create a `src` folder and a `public` folder, inside `public` create an `index.html` file and inside `src` create an `index.js` file.

Edit `index.html` and `index.js` to reflect the following:

`index.html`
```HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>React Tutorial App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
```

`index.js`
```Javascript
console.log('Hello I\'m working');
```

Now let's initialize our package management

`npm init -y`

Now let's install our core dependencies

`npm install --save react react-dom`

Your structure should look something like

```
react_app
  |- /node_modules
  	|- ...
  |- package.json
  |- /public
  	|- index.html
  |- /src
  	|- index.js
```




### React Scripts

`react-scripts` is a tool we will use to run and build our react code. The browser doesn't actually understand react, we can use `react-scripts` to create a development server which would transpile and serve our code in the browser while constantly watching for changes we make and reloading those bits. We will also use `react-scripts` to build a bundled app that we can deploy, for now let's install

`npm install --save-dev react-scripts`

Now for react scripts to work, it needs at minimum, a specific structure and some specifications in our `package.json`. For the structure it expects a `public` folder with an `index.html` file and a `src` folder with an `index.js`. As for the specifications, we have to say which browser(s) we're going to use to develop and build to support. We will add these specifications after the **devDependencies** section in our package.json

```JSON
,"browserslist": {
	"production": [
	  ">0.2%",
	  "not dead",
	  "not op_mini all"
	],
	"development": [
	  "last 1 chrome version",
	  "last 1 firefox version",
	  "last 1 safari version"
	]
}
```

The development subsection is fairly obvious, however you can read about the browserslist production values [here](https://github.com/browserslist/browserslist#queries).

Your package.json should look something like this ( exact values **WILL DIFFER DO NOT COPY** )

```JSON
{
  "name": "react_app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "react-scripts": "^5.0.1"
  },
  "browserslist": {
	"production": [
	  ">0.2%",
	  "not dead",
	  "not op_mini all"
	],
	"development": [
	  "last 1 chrome version",
	  "last 1 firefox version",
	  "last 1 safari version"
	]
   }
}
```


Now let's start our development server, navigate to the `react_app` folder and run

`npx react-scripts start`

Your browser should open to localhost:3000, with index.html loaded and index.js injected for us, so if you open the console you'll see our log 'Hello I\'m working'.


Note: There is a tool `create-react-app` that could have been used to automatically create our initial structure however when I first started out it felt a bit overwhelming and often conflated my understanding of things operated. When learning it feels much better to take things one step at a time rather than having to decipher a bunch of boilerplate code.



## The React Component

### JSX

What is JSX ? Well it stands for Javascript XML but we can basically think of it as Javascript in HTML... in Javascript. As a dumb example, think about how you would put some stored text input `text_variable` in a `<div>` tag.

Normally you would do something like add an id to the tag `<div id='some_reference'>` then grab the element using `document.getElementById('some_reference')` and then do something like set it's innerHTML to `text_variable`.

With JSX if we want to put `text_variable` in a `<div>`, we just put it
```jsx
<div>{text_variable}</div>
```

With JSX we can put any **Javascript Expression** directly into HTML by putting it into curly braces. ( Javascript Expression = any javascript code that resolves to some value ). How does this concept of Javascript Expressions in HTML helps us ? Well now we can use html almost as a template whose contents are created by our logic and data, this is the basis of a component.

### What is a Component

Components are the building blocks of react, a component can be conceptualized as a custom element that you create. This 'custom element' or component usually structured as accepting some data input and returning some JSX ( recall JSX allows us to build a template whose contents we manipulate via javascript ).

As a quick example here's a `CalculatorComponent` that accepts two parameters; two numbers `num_1`, `num_2` and then returns JSX that displays the sum.

```Javascript
const CalculatorComponent = (params) => {
	const { num_1, num_2 } = params;	// we are pulling out the two arguments we passed in num_1 and num_2, the name params is not important and can be changed
	return (<div>
		{num_1 + num_2}
	</div>)
}
```

Now we can use our component almost like any other element like `<CalculatorComponent/>` we can pass in our values similar to how normal attributes are passed in to html elements like `<CalculatorComponent num_1={3} num_2={4} />`. Now that we have some idea about components let's actually put it into action.

### Rendering React

Let's finally render our first component, to do that we'll need to use the core react libraries `react` and `react-dom`. To render react we need to (1) find a place on the DOM where we want to render our component(s) (2) actually load our component into that place. Let's do it using our `CalculatorComponent`

edit your `index.js` to reflect the following:
```Javascript
import React from 'react';
import { createRoot } from 'react-dom/client';

console.log('Hello I\'m working');

const CalculatorComponent = (params) => {
    const { num_1, num_2 } = params;    // we are pulling out the two arguments we passed in num_1 and num_2, the name params is not important and can be changed
    return (<div>
        {num_1 + num_2}
    </div>)
}

const root_element = document.getElementById('root');
const react_root = createRoot(root_element);
react_root.render(<CalculatorComponent num_1={3} num_2={4} />);
```

Once you have saved you should see a '7' appear on your browser, congratulations you've created your first react app. let's talk a bit about what's going on, first our imports; without getting into the mess of things `React from 'react'` is used to construct our Component and `{ createRoot } from 'react-dom/client'` is used to load our component onto the page. We then define our component `CalculatorComponent` using the code from before, grab the empty `div` identified by `root` ( see `index.html` ), create the root or base of our react application then finally render our component using the created root/base.

### App Structure

This was a very simple example using one file, however it's not very realistic, let's see how we can split our code across multiple files using some established conventions ( this in most cases is how you should structure and load your app ).

First let's seperate our CalculatorComponent in it's own file `Calculator.js` inside our `src` folder and make some minor modifications
```Javascript
import React from 'react';

export const Calculator = (params) => { // no need for the word 'Component' to be attached, it's already understood
    const { num_1, num_2 } = params;    // we are pulling out the two arguments we passed in num_1 and num_2, the name params is not important and can be changed
    return (<div>
        {num_1 + num_2}
    </div>)
}
```

Now let's create a component that will be used as the root of our application where we will load all other React components, we'll call the component `App`, create a new file `App.js` inside `src` and add the foll:

```Javascript
import React from 'react';
import { Calculator } from './Calculator';

export const App = () => {

    return (<div>
        <Calculator num_1={3} num_2={4} />
    </div>)
}
```
Explanation: Our `App` component imports our `Calculator` component from `Calculator.js` and uses it with `num_1` as 3 and `num_2` as 4

Finally let's modify our `index.js` to render our root/base component `App`
```Javascript
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';

console.log('Hello I\'m working');

const root_element = document.getElementById('root');
const react_root = createRoot(root_element);
react_root.render(<App/>);
```

Your file structure should look like the foll:

```
react_app
  |- /node_modules
  	|- ...
  |- package.json
  |- /public
  	|- index.html
  |- /src
  	|- index.js
  	|- App.js
  	|- Calculator.js
```
Once saved you should see the result rendered on your page.



## Events

### DOM and VDOM

The [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) is a representation of an HTML document that facilitates it's manipulation. For example when we call `document.getElementById` we retrieve a DOM node which we then use to apply changes to the document. Without going into too much depth, `react` creates it's own version of the DOM called the virtual DOM ( or VDOM ). The VDOM is used to optimize rendering, i.e. instead of replacing the entire DOM, react compares the DOM and it's VDOM and only changes what's needed in the DOM to reflect new changes. This bit is a bit beyond this tutorial, you can read more about these concepts [here](https://reactjs.org/docs/faq-internals.html) and [here](https://reactjs.org/docs/reconciliation.html).

### Synthethic Events

Since when using react we don't use the DOM directly but a representation of it, we can't use native DOM events (e.g. `onclick`) but rather synthethic events that react provides for us (e.g. `onClick`). Secondly since we're using JSX i.e. using components to create HTML in our javascript code, when we pass functions to these events we pass the function itself rather than a string. 

Traditionally it may have looked something like this
```html
<button onclick='handleOnClick'> 
	Click 
</button>
```

In `react` using JSX we have
```JSX
<button onClick={handleOnClick}> 
	Click 
</button>
```

Again, note `onclick` is the native DOM event which we replaced by `react`'s synthethic event `onClick`, case being the only difference (lowercase vs cammel case), this is done by design to make things easy to remember yet distinct; and secondly instead of using a string of the function we pass in the function itself ( again JSX ).


## State

### useState

State, simplified, is variables. State within your app can be thought of then as, all the data currently loaded within your application. Let's zoom in a bit, to the state for a component i.e. the data / variables within the component. State can be thought of as the core `react`, why ? Components update their content ( or react to ) the data within them. Therefore when working with data within a component i.e. when we create 'variables' or state, we have to do so in a way react can keep track of it. We create these 'variables' or state by calling `useState` function. 

When we call `useState` there are 3 things to note; (1) a `react` variable, (2) a function to update this `react` variable, and (3) what the default value of this `react` variable should be. Let's see a quick example of `useState`, we will use it to keep track of a count

```JSX
const [count, updateCount] = useState(0);
```

In the example, (1) `count` is the special `react` variable, (2) `updateCount` is the function we use to update the value of `count`, and `0` is `count`'s initial value.


### REACTing to state

In order to fully appreciate how state works, we need to actually use it. let's create a component to count based on user inputs, we'll call it `Counter` and create it in `Calculator.js`.


Edit `Calculator.js` to reflect the foll:

```Javascript
import React, { useState } from 'react';

export const Calculator = (params) => { // no need for the word 'Component' to be attached, it's already understood
    const { num_1, num_2 } = params;    // we are pulling out the two arguments we passed in num_1 and num_2, the name params is not important and can be changed
    return (<div>
        {num_1 + num_2}
    </div>)
}

export const Counter = () => {
    const [count, updateCount] = useState(0);// useState creates our variable 'count' and a function 'updateCount' to update our variable;

    const handleCountBtnClick = (ev) => {
        updateCount(count + 1); // a replacement for count = count + 1
    }

    return (<div>
        Clicked {count} times.
        <button onClick={handleCountBtnClick}> Click</button>
    </div>)
}
```

Now all let's add `Counter` to our `App` component, edit `App.js` to reflect the following:

```Javascript
import React from 'react';
import { Calculator, Counter } from './Calculator';

export const App = () => {

    return (<div>
        <Counter />
        <Calculator num_1={3} num_2={3} />
    </div>)
}
```

Your page should automatically refresh with our `Counter` component loaded, now whenever you click the button, the count should increase.



## Hooks

### Hooks

[Hooks](https://reactjs.org/docs/hooks-overview.html) are a bunch of functions that allows us to use react features easily. `useState` is actually an example of a hook, as seen it allows us to create special `react` state that our components use update it's content. 

### useEffect

`useEffect` is the next most popular hook, it allows us to perform 'effects' between changes in specific states. `useEffect` has two bits to take note of, (1) the functionality or 'effect' we want run, and (2) the pieces of state we want to run the 'effect' inbetween. 

As an example, let us modify our `Calculator` to take in two user inputs `num_1`, `num_2` and an operator `operator`, our calculator will work such that if `num_1`, `num_2` or `operator` changes we will attempt to recalculate the result live. To do this, of course we will use a `useEffect`, the effect will be calculating a result, and the pieces of state we will be observing will be `num_1`, `num_2` and `operator` because if any of these changes then we will need to recalculate the result.

```Javascript
import React, { useState, useEffect } from 'react';

export const Calculator = (params) => { // no need for the word 'Component' to be attached, it's already understood
    const [num_1, updateNum1] = useState(0);
    const [num_2, updateNum2] = useState(0);
    const [result, updateResult] = useState('0')
    const [operator, updateOperator] = useState('+');

    const calculate = () => {
        let updated_result = '';
        if (operator == '+')
            updated_result = num_1 + num_2;
        else if (operator == '-')
            updated_result = num_1 - num_2;
        else if (operator == '/')
            updated_result = num_1 / num_2;
        else if (operator == '*')
            updated_result = num_1 * num_2;
        else
            updated_result = 'Invalid Operator';

        updateResult(updated_result);
    }

    useEffect(calculate, [num_1, num_2, operator]);

    const handleOnChange = (ev, field) => {
        const new_value = ev.target.value;
        if (!new_value) // if input changed to nothing / null, then don't update anything
            return;
        if (field == 'num_1')
            updateNum1(parseInt(new_value));
        else if (field == 'num_2')
            updateNum2(parseInt(new_value));
        else
            updateOperator(new_value)
    }

    return (<div>
        <input type='number' defaultValue='0' onChange={ev => handleOnChange(ev, 'num_1')} />
        <input type='character' defaultValue='+' onChange={ev => handleOnChange(ev, 'operator')} />
        <input type='number' defaultValue='0' onChange={ev => handleOnChange(ev, 'num_2')} />
        =
        {result}
    </div>)
}

export const Counter = () => {
    const [count, updateCount] = useState(0);// useState creates our variable 'count' and a function 'updateCount' to update our variable;

    const handleCountBtnClick = (ev) => {
        updateCount(count + 1); // a replacement for count = count + 1
    }

    return (<div>
        Clicked {count} times.
        <button onClick={handleCountBtnClick}> Click</button>
    </div>)
}
```

Let's take a minute to dissect what's here, in order;

First we used `useState` 4 times to create 4 pieces of state, functions to update them, and gave them default values. 
```Javascript
	const [num_1, updateNum1] = useState(0);
    const [num_2, updateNum2] = useState(0);
    const [result, updateResult] = useState('0')
    const [operator, updateOperator] = useState('+');
```

Then we created a calculate function, which uses `num_1`, `num_2` and `operator` to calculate and update `result`.
```Javascript
	const calculate = () => {
        let updated_result = '';
        if (operator == '+')
            updated_result = num_1 + num_2;
        else if (operator == '-')
            updated_result = num_1 - num_2;
        else if (operator == '/')
            updated_result = num_1 / num_2;
        else if (operator == '*')
            updated_result = num_1 * num_2;
        else
            updated_result = 'Invalid Operator';

        updateResult(updated_result);
    }
```

We then used a `useEffect` to say anytime `num_1`, `num_2`, or `operator` changes run the calculate function, as shown `useEffect` is a function call that accepts 2 things, (1) the functionality or 'effect' we want run in this case `calculate`, and (2) the states we want to observe or rather states which affect our 'effect' in this case `num_1`, `num_2`, and `operator`. 

```Javascript
useEffect(calculate, [num_1, num_2, operator]);
```

The rest are things we've already gone over, `handleOnChange` is a function we create to handle the changing of something, it accepts the actual change event `ev` as well as some identifying keyword `state_name`, it uses the event `ev` to fetch the current entered and based on the keyword `state_name` we update the relevant piece of state.

```Javascript
	const handleOnChange = (ev, state_name) => {
        const new_value = ev.target.value;
        if (!new_value) // if input changed to nothing / null, then don't update anything
            return;
        if (state_name == 'num_1')
            updateNum1(parseInt(new_value));
        else if (state_name == 'num_2')
            updateNum2(parseInt(new_value));
        else
            updateOperator(new_value)
    }
```
Finally we have the JSX where we define our inputs to call our `handleOnChange` function by attaching it to `react`'s synthethic `onChange` event, however we wrap this function call in an anonymous function so that we can pass a specific keyword for each input.

```JSX
	return (<div>
        <input type='number' defaultValue='0' onChange={ev => handleOnChange(ev, 'num_1')} />
        <input type='character' defaultValue='+' onChange={ev => handleOnChange(ev, 'operator')} />
        <input type='number' defaultValue='0' onChange={ev => handleOnChange(ev, 'num_2')} />
        =
        {result}
    </div>)
```


## Routing

### Why Have Routes ?

Modern frontend frameworks operate on the basis that the entire app operates on a single page ( single page apps ). However, we still like the illusion of routing to different pages ( this can also be useful to the user since they often identify and navigate directly to a specific view by typing in the route ). It is entirely possible ( not recommended ) to build your own routing system however there's also `react-router-dom` which is the defacto routing solution used for `react`.

### Basic React Router

`react-router-dom` is a library that provides routing for `react`. To get started lets install `react-router-dom` run

`npm install react-router-dom`

To get started we need to the root of our application in a Component from `react-router-dom` called `BrowserRouter`, let's modify our `index.js` to reflect the foll:

```Javascript
import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { App } from './App';

console.log('Hello I\'m working');

const root_element = document.getElementById('root');
const react_root = createRoot(root_element);
react_root.render(<BrowserRouter>
    <App />
</BrowserRouter>);
```
Now let's modify `App` to have two routes, `/counter` for our `Counter` and `/calculator` for `Calculator`, to do this we'll need to use the `Routes` and `Route` components from `react-router-dom`. `Routes` is where we initialize the routes for our application, it will contain all the `Route` components for our app. Each `Route` component is simply a path e.g. `/calculator` and what to render e.g. `<Calculator/>` let's edit `App.js` to see these in action :

```Javascript
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { Calculator, Counter } from './Calculator';

export const App = () => {

    return (<div>
        <Routes>
            <Route path='/counter' element={<Counter />} />
            <Route path='/calculator' element={<Calculator />} />
        </Routes>
    </div>)
}
```
Now when you visit `/counter` you'll see our Counter component and when you visit `/calculator` you'll see our calculator component (easy right!).

Remember this is an illusion of different routes, we will not actually serve different pages; visting `/calculator` loads the same page, the same code, but the Component specific to `/calculator`; simply put `BrowserRouter` must read the state of the browser and load the required Component / View. However there are many more things that `BrowserRouter` does for us right out of the box, a quick example is keeping track of where the user has visited and facilitating backwards and forwards navigation between routes. Again remember these routes aren't real we are never leaving the page so there isn't anyting to go back or forward to. You can read more about react router [here](https://reactrouter.com/docs/en/v6/getting-started/overview).

### Routing Necessities

You'll very quickly notice, that the base of our application has nothing loaded i.e. if you go to `localhost:3000` you'll see nothing, this is because we do not have a `Route` for our base path `/`, therefore nothing will load, there are a few options we will explore

OPTION 1: The most obvious let's just add Route and choose a component e.g. `Calculator`, 

```Javascript
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { Calculator, Counter } from './Calculator';

export const App = () => {

    return (<div>
        <Routes>
            <Route path='/' element={<Calculator />} />
            <Route path='/counter' element={<Counter />} />
            <Route path='/calculator' element={<Calculator />} />
        </Routes>
    </div>)
}
```
This works fine, Components are meant to be reusable so no problems here, but a bit crude

OPTION 2: If we don't have something for a particular route e.g. `/` we can redirect them to one, let's redirect `/` to `calculator`

```Javascript
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Calculator, Counter } from './Calculator';

export const App = () => {

    return (<div>
        <Routes>
            {/* <Route path='/' element={<Calculator />} /> */}
            <Route path='/' element={<Navigate to='/calculator' replace={true} />} />
            <Route path='/counter' element={<Counter />} />
            <Route path='/calculator' element={<Calculator />} />
        </Routes>
    </div>)
}
```

Again works fine, demonstrates how to render a redirect such within `BrowserRouter` so `BrowserRouter` can keep track of where user has been.

OPTION 3: Create a new component that acts as a menu

In `src` create a new file `Menu.js` and add the following:

```Javascript
import React from 'react';
import { Link } from 'react-router-dom';

export const Menu = () => {

    return (<div>
        Most desolate menu in the world
        <ul>
            <li>
                <Link to='/calculator'>Calculator ( ಠ ʖ̯ ಠ ) </Link>
            </li>
            <li>
                <Link to='/counter'>Counter ◔_◔ </Link>
            </li>
        </ul>

    </div>)
}
```

Now edit `App.js`

```Javascript
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Calculator, Counter } from './Calculator';
import { Menu } from './Menu';

export const App = () => {

    return (<div>
        <Routes>
            {/* <Route path='/' element={<Calculator />} /> */}
            {/* <Route path='/' element={<Navigate to='/calculator' replace={true} />} /> */}
            <Route path='/' element={<Menu />} />
            <Route path='/counter' element={<Counter />} />
            <Route path='/calculator' element={<Calculator />} />
        </Routes>
    </div>)
}
```

Once you've saved, the base route will now render our very ugly menu Menu. `React Router` has a lot more and [very good documentation](https://reactrouter.com/docs/en/v6/getting-started/overview), please give it a read through if you ever find yourself amiss with routing.



## Extra Bits

### Conventions

A lot of the code I wrote was done to maximize readability however in practice there are some things that are common place.

#### Param Destructuring

This is how we access properties / parameters for a component, let's look back at the first version of `<Calculator\>`, for reference
```Javascript
const CalculatorComponent = (params) => {
	const { num_1, num_2 } = params;	// we are pulling out the two arguments we passed in num_1 and num_2, the name params is not important and can be changed
	...
}
```
We accepted an object we named 'params' and then proceeded to destructure and pull our `num_1` and `num_2` however in practice the norm is to destructure in the method signature / parameter list itself like so
```Javascript
const CalculatorComponent = ({num_1, num_2}) => { // we are expecting two properties to be passed, called exactly `num_1` and `num_2`, we can therefore pull them out immediately
	...
}
```

#### useEffect 

When we used the `useEffect` we created a function `calculate` to pass into the `useEffect`
reference
``` Javascript
const calculate = () => {
        let updated_result = '';
        if (operator == '+')
            updated_result = num_1 + num_2;
        else if (operator == '-')
            updated_result = num_1 - num_2;
        else if (operator == '/')
            updated_result = num_1 / num_2;
        else if (operator == '*')
            updated_result = num_1 * num_2;
        else
            updated_result = 'Invalid Operator';

        updateResult(updated_result);
    }

    useEffect(calculate, [num_1, num_2, operator]);
```

However the 'effects' or functionality in `useEffects` are usually only meant to be triggered in the `useEffect` so people usually use an [anonymous function](https://www.geeksforgeeks.org/javascript-anonymous-functions/) or rather ES6's version, an unassigned [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), and write the functionality directly in the body

``` Javascript
    useEffect(()=>{
        let updated_result = '';
        if (operator == '+')
            updated_result = num_1 + num_2;
        else if (operator == '-')
            updated_result = num_1 - num_2;
        else if (operator == '/')
            updated_result = num_1 / num_2;
        else if (operator == '*')
            updated_result = num_1 * num_2;
        else
            updated_result = 'Invalid Operator';

        updateResult(updated_result);
    }), [num_1, num_2, operator]);
```

As you can see the body of the functions are exactly the same, the only difference is we just wrote it directly in the `useEffect` using an unassigned arrow function.



## Sample Network Request and Render

As a quick example of how we can do network requests and render the results I'm going to fetch art pieces using [The Art Institute of Chicago API]( https://api.artic.edu/docs ). 
Let's begin by installing axios to make making requests easier.

`npm install --save axios`

Now create an `Art.js` in `src`, we'll have two components `Art` being the main component and `ArtPiece` being an individual art piece. The code here will be a bit closer to how things would usually be done

```Javascript
import Axios from 'axios';
import React, { useRef, useState } from 'react';

export const Art = () => {
    const [art_data, updateArtData] = useState([]);
    const searchInput = useRef(null); // holds a reference to an element

    const handleSearchArt = (ev) => {
        const title = searchInput.current.value; // similar to title = document.getElementById('search-text-input').value;
        const params = { q: title, limit: 5, fields: 'id,title,image_id,artist_display' }; // sample set of params, limits the number of results to 5, and only returns the id, title, image_id, and artist_display fields    
        Axios.request({
            url: 'https://api.artic.edu/api/v1/artworks/search',
            params
        }).then(res => {
            const { config, data } = res.data;
            const updated_art_data = data.map(artPiece => ({ config, ...artPiece })); // add config to each art piece
            updateArtData(updated_art_data);
        }).catch(err => console.log(err));
    }

    return (<div>
        <input ref={searchInput} id='search-text-input' type='text' />
        <button onClick={handleSearchArt}> search </button>
        {art_data.map(art_piece_data => (<ArtPiece key={art_piece_data.id} {...art_piece_data} />))} 
        {/* Don't be overwhelmed by {...art_piece_data} this is another example of destructuring, each key,value pair is passed down as if it were independent */}
    </div>)
}

// Again we pull out each argument passed by name using destructuring
const ArtPiece = ({ config, title, image_id, id, artist_display }) => {
    return (<div>
        <img src={`${config.iiif_url}/${image_id}/full/843,/0/default.jpg`} />
        <h3>{title}</h3>
        <p>{artist_display}</p>
    </div>)
}
```
`useRef` is an example of a hook we can use to hold a reference to an element, in this case we used it to hold a reference to our search input element; The `id` is left in for comparison.
Now we simply need to add a route to load `Art`, edit `App.js` 

```Javascript
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Art } from './Art';
import { Calculator, Counter } from './Calculator';
import { Menu } from './Menu';

export const App = () => {

    return (<div>
        <Routes>
            {/* <Route path='/' element={<Calculator />} /> */}
            {/* <Route path='/' element={<Navigate to='/calculator' replace={true} />} /> */}
            <Route path='/' element={<Menu />} />
            <Route path='/counter' element={<Counter />} />
            <Route path='/calculator' element={<Calculator />} />
            <Route path='/art' element={<Art />} />
        </Routes>
    </div>)
}
```

We can access our `/art` and search for art pieces, feel free to add it to the great menu :P


## Final Thoughts

There you have it, a basic yet somewhat comprehensive ( I hope ) guide on react, there are many more concepts, however, I'd say those are much more advanced and will only serve to conflate someone's understanding if they're new to react. Not to worry you WILL eventually encounter them, as for me I may or may not make an advanced guide, I suppose it depends on demand  either way, let me know in the comments, and thank you very very much for reading this far <3 (◠﹏◠). 

Edit: to include css, import your css file in index.html as you normally would ( doing a webpack config is a bit too much for introductory purposes ).