# Modern React and Redux
AirBnB convention (opens new window)
# 1. Dive in
# First Look
App function is a React Component
Component have two jobs.
- return JSX
 - handles events
 
All components return JSX : instructions that tell React what to show on screen. Looks similar to HTML.
JSX elements
- Return HTML element
 - Return another component
 

React iterates over every element in JSX.
Check if DOM element. Yes? Show on screen.
No? Call the component function and iterate through it again.
ReactDOM.render(<App />, document.getElementById("root"))
 First argument : get App function, get JSX, render into HTML
Second argument : Then take the HTML and place it inside the div with this ID in index.html.
The two libraries.
React : Reconciler. Gets components, JSX and iterate through it to make HTML or get more components.
ReactDOM : Renderer. Actually create HTML and put it to DOM.
useState : Works with React's state system. Used to update contents on the screen.
# Generating a React Project
npx create-react-app myapp
npm init react-app my-app
yarn create react-app my-app
# npm vs npx vs yarn
npx allows us to execute it quick.
# What is create-react-app?
Install over 1782 packages. Most importantly, Babel, Webpack and Dev server.
Babel : Since 2015, ES is upgraded and new syntax are made. However, browsers' support for newer ES is poor. Babel changes newer version of ES into largely supported version.
Webpack:
Dev Server :
# Project Directory

# JSX
React works by creating JSX files. Having HTML right inside of JS files. Compiler, which is known as Babel, changes the JSX into a plain Javascript.


Babel changes JSX into HTML using React.createElement functions

# Template literals = String interpolation
<h1>Hello {`${fName} ${lName}`}</h1>
 Outer bracket means JS in JSX.
Backtick means template literals, meaning these will be strings.
Inner bracket means JS inside template literals.
# Component

// Import the React and ReactDOM libraries
import React from "react";
import ReactDOM from "react-dom";
// Create a React component
const App = function () {
    return (
        <div>
            <label htmlFor="name" className="label">Enter name:</label>
            <input type="text" id="name" />
            <button style="background-color:blue; color:white;"></button>
      </div>
  )
// Take the React component and show on screen
ReactDOM.render(<App />, document.querySelector("#root"));
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- You MUST write component in the same line as return
 - If you don't there will be an error.
 - Common practice is to write parenthesis on the first line.
 
# Inline styling with JSX

Outer parenthesis declares we want to reference JS variable.
Second parenthesis declares JS object.
Any kebab casing turns into camel casing.
value is enclosed with quote marks
semicolons are removed and comma is used. Because this is a JS object.
Convention demands use double quotes with JSX properties. None JSX property should use single quotes. Lots of companies use double quotes everywhere. Your choice.
# Class with JSX
The keyword 'class' is reserved for JS class in JSX. We have to use className instead. There is a discuss about removing className and just using class because React is becoming smarter.
# JSX can reference JS variables
const App = function () {
  const buttonText = "Click Me!";
  return (
    <div>
      <button>
        {buttonText}
      </button>
    </div>
  );
};
 2
3
4
5
6
7
8
9
10
11
{buttonText} the parenthesis tells 'I want to use a JS variable'.
Limitation
It's ok to put
strings,integers,arraysto the JS variable.But if you put
object, you will have an error:
function getButtonText(){
    return 'Click on me!'
}
const App = function () {
  return (
    <div>
      <button>
        {getButtonText()}
      </button>
    </div>
  );
};
 2
3
4
5
6
7
8
9
10
11
12
13
Function can be used instead as well.
# 3. Communicating with Props
React components are written in 'ReactComponent' style. Not kebab, snake, or camel. Every component in React is independent. It must be exported and imported for 'component nesting'.
// CommentDetail.js
export default CommentDetail;
// index.js
import CommentDetail from './CommentDetail'
<CommentDetail />
 2
3
4
5
6
- In relative path, 
./states the current folder. - Components don't use curly braces. Treated as JSX tag.
 - Props : System for passing data from a parent component to child component.
 
// property name = "value"
<CommentDetail author="Coco" />
 2
const CommentDetail = (props)=>{
    console.log(props)
    //{author:"coco"}
    return(
    	<div>
        	{props.author}
        </div>
    )
}
 2
3
4
5
6
7
8
9
# html attribute vs react props


attributes are predefined, props are customizable
key is a special property and does not act as props.
# Prop to prop
<ApprovalCard>
    <CommentDetail
        author="Keith"
        time="Today at 15:01"
        content="yeah"
        avatar={faker.image.image()}
        />
</ApprovalCard>
 2
3
4
5
6
7
8
9
const ApprovalCard = (props)=>{
    return (
    	<div>
        	{props.children}
        </div>
    )
}
 2
3
4
5
6
7
8
- You can put prop inside a prop.
 - It will be sent down as 
props.children. Everything between the tag will be represented asprops.childern. 
# mapping object to props
const contacts = [
  {
    name: "Beyonce",
    img:
      "https://blackhistorywall.files.wordpress.com/2010/02/picture-device-independent-bitmap-119.jpg",
    phone: "+123 456 789",
    email: "b@beyonce.com"
  },
  {
    name: "Jack Bauer",
    img:
      "https://pbs.twimg.com/profile_images/625247595825246208/X3XLea04_400x400.jpg",
    phone: "+123 456 789",
    email: "jack@nowhere.com"
  },
  {
    name: "Chuck Norris",
    img:
      "https://i.pinimg.com/originals/e3/94/47/e39447de921955826b1e498ccf9a39af.png",
    phone: "+123 456 789",
    email: "gmail@chucknorris.com"
  }
];
const rendered_contacts = contacts.map((contact) => {
  return (
    <Card
      name={contact.name}
      img={contact.img}
      phone={contact.phone}
      email={contact.email}
    />
  );
});
ReactDOM.render(
  <div>{rendered_contacts}</div>)
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 4. Structuring Apps with Class-based Components
# React in the Past
Functional components used to produce JSX to show content to user.
Class components were used to produce JSX to show content to user & use lifecycle method to run code at specific points & use state system to update content on screen
Functional components were much more restricted. But now it became more dynamic

Which one should we use?
Companies with established projects are using class-based components because this used to be the way.
Newer projects use either one.
You must understand both.
Learn class-based -> function-based -> redux
# Geolocation API
window.navigator.geolocation.getCurrentPosition(successCallback(){}, failureCallback(){})
    window.navigator.geolocation.getCurrentPosition(
        (position) =>  console.log(position) , 
        (err) => console.log(err)
    )
 2
3
4
5
6
# Lifecycle of functional component

Getting geolocation service takes some time because it uses API.
Problem is when we get result of geolocation, the screen is already rendered!
There must be a way to 'pause' or 'rerender' the updated part.
Class component must be used to update screen.
# Rule of Class components
- Must be a Javascript Class. Different from Ruby or Java's object oriented class inheritance. JS uses prototypal inheritance. But works like class in this case
 - Must extend React.component
 - Must define render method that returns JSX
 
class App extends React.Component{
    render() {
        return <div> Latitude: </div>
    }
}
 2
3
4
5
When class is made, JS class only has render method. React expects many more methods and these are implemented in React.Component. By using extends we are creating a sub-class.
# State in React Components
Using class component is not enough to rerender updated screen.
- Understanding state will open new understandings
 - But it is difficult and challenging.
 
# Rules of state
Only usable with class components. (can be used with functional using the hooks system)
It's confusing with props. Props vs States
State is a JS object that contains data strictly relevant to a component.
Updating state causes rerendering of the componenet.
State must be initialized when component is created.
State can only be updated using the function
setState.
# Initializing
class App extends React.Component{
   constructor(props){
       super(props)
       this.state = {lat: null}
   }       
   
    render() {
        return <div> Latitude: {this.state.lat} </div>
    }
}
 2
3
4
5
6
7
8
9
10
11
- Constructor is specific to JS not only React. Any time a new instance is created, constructor function is instantly called before anything else. This makes it a good place to initializing state.
 - The 
supermethod is called fromReact.Component. We are replacing the javascript constructor method with react'sconstructormethod. To make sureReact.Component'sconstructormethod is called, we statesuper(props). 
# setState
// right way
this.setState({ lat: position.coords.latitude });
// NEVER DO THIS. Only exception is when we initialize.
this.state.lat = position.coords.latitude
 2
3
4
5
this.statedirect assignment is only used on initialization
# App lifecycle walkthrough
What happens?
- JS file loaded by browser
 - Instance of App component created
 - Constructor function gets called. (super needed)
 - Initialized state object with properties of interest. 
this.stateis a very special name and cannot be named else. - Call async API. The callback function is not executed until some time in the future but the constructor finishes before.
 Rendermethod executed.- App returns JSX and rendered to HTML.
 - API request responsed.
 this.setStateupdates our state- React checks update and runs 
rendermethod one more time. - Updated JSX returned.
 - Screen updated.
 
App component is rendered twice.
# Handling errors (with grace)
For better UX

  render() {
    if (this.state.errorMessage && !this.state.lat) {
      return <div> Error: {this.state.errorMessage} </div>;
    }
    if (!this.state.errorMessage && this.state.lat) {
      return <div>Latitude : {this.state.lat} </div>;
    }
    return <div>Loading!</div>;
  }
 2
3
4
5
6
7
8
9
10
- conditional rendering.
 
# componentDidMount
When I refresh too quick repeatedly, I get

# 6. Lifecycle Methods
We've already seen constructor function. We've also seen render method. Render method is not optional unlike others. Let's see what other methods there are

// Called one time after rendered
componentDidMount(){}
// Called each time updated
componentDidUpdate(){}
 2
3
4
5
After placing window.navigator.geolocation.getCurrentPosition in the componentDidMount, the error
went away.
Do not do dataloading in constructor. setState can only happen to components that are mounted.
# Alternate way to initialize state
constructor(props) {
    super(props);
    this.state = { lat: null, errorMessage: "" };
}
// Same as below. Babel will build up the constructor for us.
state = { lat: null, errorMessage: '' };
 2
3
4
5
6
7
This makes it simpler. Since constructor method is only used to initialize states, this is a good way to do it.
# Expression vs Statement
An expression evaluates to a value. A statement does something. Statements represent an action or command e.g print statements, assignment statements. Expression is a combination of variables, operations and values that yields a result value.
- Statement : 
ifswitchstatements that to conditional stuffs. - Expression : simple return value.
 
# JSX {} can only contain expressions, not statements
function App(){
  return <div>
  {if(isLoggedIn ===true){
    return <h1> Hellow</h1>;
  }else{
          return <Login />
         }}
	</div>
}
 2
3
4
5
6
7
8
9
- This does not work because statement is inside {}.
 
# JS ternary operator(inline condition)
CONDITION ? DO IF TRUE : DO IF FALSE
 - By using ternary operator, the 
if elsestatement changed into expressions. 
//getting the current season
function App(){
  return <div>
    {isLoggedIn === true ? <h1>Hello</h1> : <Login/>}
  </div>
}
 2
3
4
5
6
7
8
# semantic-ui icons
const icon = season === "winter" ? "snowflake" : "sun";
<i className={`${icon} icon`}></i>
 2
# configuring options and destructuring
const seasonConfig = {
    summer: {
        text: 'let\'s hit the beach',
        iconName: 'summer'
    },
    winter: {
        text: 'burr it\'s chilly',
        iconName: 'winter'
    }
}
.
.
.
const season = getSeason(props.lat, new Date().getMonth());
//deestructuring
const { text, iconName} = seasonConfig[season]
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# importing CSS in React
import './SeasonDisplay.css'
 - Webpack will see the the import, and stick it to 
index.html. 
# Default Props
// First way
const AppName = (props)=>{
    return (
        {props.message || 'Loading'}
    )
}
// The beautiful way
AppName.defaultProps = {
    message:"Loading..."
}
 2
3
4
5
6
7
8
9
10
11
12
- Great to make reusable elements.
 
# props combined with ternary expressions
//App.js
import React from "react";
import Form from "./Form";
var userIsRegistered = false;
function App() {
  return (
    <div className="container">
      <Form userIsRegistered={userIsRegistered} />
    </div>
  );
}
export default App;
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Form.js
import React from "react";
function Form(props) {
  return (
    <form className="form">
      <input type="text" placeholder="Username" />
      <input type="password" placeholder="Password" />
      {!props.userIsRegistered && (
        <input type="password" placeholder="Confirm Password" />
      )}
      <button type="submit">
        {props.userIsRegistered ? "Login" : "Register"}
      </button>
    </form>
  );
}
export default Form;
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Summary of Class Components



+State can only be updated using the function setState
# Clock
    class Clock extends React.Component {
        state ={time:new Date().toLocaleTimeString()}
        
        componentDidMount() {
            setInterval(() => {
                this.setState({time: new Date().toLocaleTimeString()})
            }, 1000)
        }
        
        render() {
            return (
                <div className="time">
                    The time is: {this.state.time}
                </div>
            );
        }
    }
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Hoisting
This should be on JS md. Move later
- Hoisting means getting assigned before it should happen.
 
console.log(animal)
var animal = "Coco"
console.log(animal)
// Undefined
// Coco
console.log(animal)
let animal = "Coco"
console.log(animal)
// ReferenceError : cannot access before initiaization
 2
3
4
5
6
7
8
9
10
11
- In the first case, JS knew that 
animalwould be declared before actually it was. This is called hoisting and happens tovar - It can also happen to functions.
 
howl();
function howl(){
    console.log('woof')
}
// woof
hoot();
const hoot = function(){
    console.log('hoo hoo')
}
// ReferenceError : cannot access 'hoot' before initialization
hoot();
var hoot = function(){
    console.log('hoo hoo')
}
console.log(hoot)
// TypeError : hoot is not a function (Type is Undefined)
// (if executed) Undefined
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- function declarations are hoisted. These can thought that they are placed on the top of the JS file.
 - function expressions are not hoisted.
 
# 7. Handling User Input with Forms and Events
# onChange
class SearchBar extends React.Component {
  onInputChange(event) {
    console.log(event.target.value);
  }
  render() {
    return (
      <div>
        <form>
              <input
                type="text"
                onChange={this.onInputChange}
              />
        </form>
      </div>
    );
  }
}
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
onChange,onClickandonSubmitare special names.onChange={this.onInputChange}NotonChange={this.onInputChange()}Because we do not want to execute it everytime its rendered. Its a reference of callback function so we can use it sometime in the future.
# onChange alternate: inline arrow function callback
<input type="text" onChange={(event)=>{console.log(event.target.value)}} />
 - Can use anonymous arrow function instead of separate function
 
# Controlled vs Uncontrolled element
What we did before was uncontrolled element. Below is controlled element made by using state.
class SearchBar extends React.Component {
  state = {term:""}
  render() {
    return (
      <div>
        <form>
              <input
                type="text" value = {this.state.term}
                onChange=(e)=>{this.setState({term:e.target.value})}
              />
        </form>
      </div>
    );
  }
}
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stateis made and it's synchronized with theinputwith thevalueproperty.- Because it uses 
setStatecomponent is rerendered everytime. - This is better because information is stored inside the React area not in the html & DOM area.
 - This makes certain manipulations very easy.
this.setState({ term: e.target.value.toUpperCase() });
 
# this

class Car {
  setSound(sound){
    this.sound = sound
  }
  drive(){
    return this.sound;
  }
}
const car = new Car();
car.setSound('vroom')
const truck = {
  sound: 'putput'
  driveMyTruck:car.drive
}
truck.driveMyTruck()
//putput
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
driveMyTruck()callscar.drive.car.drivecallsthis.sound. At this point, althoughthiswascarfor car, becausethisis being called fromtruck,thisis assigned totruck.thisis not assigned when it's being made but when it's being executed.
# binding this
Legacy way
class Car {
  constructor(){
    this.drive = this.drive.bind(this)
  }
}
 2
3
4
5
Using arrow function
onFormSubmit(e){
  this.setState({term:e.target.value})
}
// upper is shorthand notation for below
onFormSubmit = function(e){
  this.setState({term:e.target.value})
}
// We can use arrow function
onFormSubmit = (e)=>{
  this.setState({term:e.target.value})
}
 2
3
4
5
6
7
8
9
10
11
12
13
14
- arrow function do not default 
thisto the window scope, rather they execute in the scope - arrow function does not have its own 
this. Thethisvalue of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching forthiswhich is not present in the current scope, an arrow function ends up finding thethisfrom its enclosing scope. 
Final method : Using anonymous arrow function inline.
onChange={(e) => {this.setState({ term:e.target.value });
}}
 2
# Communicating Child to Parent

//App.js
class App extends React.Component {
  onSearchSubmit(term) {
    console.log(term)
  }
  render() {
    return (
      <div>
      	//onSubmit is NOT a specific name. Changable.
        <SearchBar onSubmit={this.onSearchSubmit}/>
      </div>
    );
  }
}
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
///SearchBar.js
  state = { term: "" };
  onFormSubmit = (event) => {
    event.preventDefault();
    this.props.onSubmit(this.state.term)
  }
 2
3
4
5
6
7
this.props.is used to get the passed down props function.- parent function is passed down as props. Searched term is sent to the parent function. Function is run at parent component.
 
# 8. Making API requests
Sending request to unsplash API
# Axios vs Fetch
yarn add axios
Axios is 3rd party package, and fetch is built into browsers. Axios can be very easily installed using npm. Fetch is far more basic and lower level. You will have to write lot of code that is already written in axios.
Highly recommend to use axios.
// 3rd party import is placed above my components
import React from "react";
import axios from "axios";
import SearchBar from "./SearchBar";
class App extends React.Component {
  onSearchSubmit(term) {
    axios.get(`https://api.unsplash.com/search/photos`, {
      params: { query: term },
      headers: {
        Authorization: "Client-ID kdfkldsljfrMYIDlsjfklsdc",
      },
    });}
 2
3
4
5
6
7
8
9
10
11
12
13
14
# Request with Async and Await
Two methods. async is newer and better
then()
A promise object is always returned after axios use.then() function to chain. Anytime you are working with promise, you can use then.
axios.get(`https://api.unsplash.com/search/photos`, {
  params: { query: term },
  headers: {
    Authorization: "Client-ID KBHNjiOkkI7vlg-CmyRoIy29kQcZ37eTv0EoC0sgIzc",
  },
})
.then((response) => {
        console.log(response.data.results);;
 2
3
4
5
6
7
8
async await
state = { images: [] };
async onSearchSubmit(term) {
  const response = await axios.get(`https://api.unsplash.com/search/photos`, {
    params: { query: term },
    headers: {
      Authorization: "Client-ID KBHNjiOkkI7vlg-CmyRoIy29kQcZ37eTv0EoC0sgIzc",
    },
  });
  console.log(response)
  this.setState({ images: response.data.results });
}
 2
3
4
5
6
7
8
9
10
11
# Binding Callbacks

This error occurs because this in this.state does not point to the App class. It instead points to the props of SearchBar.
onSubmit is sent down to SearchBar component as props. It is then executed via this.props.onSubmit(this.state.term). onSubmit is executed on props so the this directs to the props of SearchBar component.
Refactored as arrow function to fix the this context.
onSearchSubmit = async (term) => {
  const response = await axios.get(`https://api.unsplash.com/search/photos`, {
    params: { query: term },
    headers: {
      Authorization: "Client-ID KBHNjiOkkI7vlg-CmyRoIy29kQcZ37eTv0EoC0sgIzc",
    },
  });
  this.setState({ images: response.data.results });
}
 2
3
4
5
6
7
8
9
10
# Creating Custom Clients
//unsplash.js
import axios from "axios";
export default axios.create({
  baseURL: "https://api.unsplash.com",
  headers: {
    Authorization: "Client-ID KBHNjMYIDzc",
  },
});
 2
3
4
5
6
7
8
9
10
11
//App.js
import unsplash from "../api/unsplash";
onSearchSubmit = async (term) => {
  const response = await unsplash.get(`/search/photos`, {
    params: { query: term },
  });
  this.setState({ images: response.data.results });
};
 2
3
4
5
6
7
8
9
# 9. Building Lists of Records

# map function in javascript
const numbers = [0, 1, 2, 3, 4];
let newNumbers=[]
const new_numbers = numbers.map((num)=>{
	return num * 10
})
 2
3
4
5
6
7
# Getting lists from props
const ImageList = (props) => {
  const images = props.images.map((image) => {
    return <img src={image.urls.regular} alt={image.alt_description}></img>;
  });
  return <div>{images}</div>;
};
 2
3
4
5
6
# Keys in props
Purpose
React uses key to identify which list is updated by comparing the keys and the value.
Implementation
<img key={image.id} src={image.urls.regular} alt={image.alt_description} />
 destructuring
const images = props.images.map((image) => {
  return (
    <img key={image.id} src={image.urls.regular} alt=image.alt_description}
/>
  );
});
// destructured
const images = props.images.map(({id, urls, alt_description}) => {
  return (
    <img key={id} src={urls.regular} alt=alt_description}
/>
  );
});
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Accessing the DOM with Refs

Vanila JS : document.querySelector('img').clientHeight
React Refs gives access to a single DOM element. We create refs in the constructor, assign them to instance variables, then pass to a particular JSX element as props.
constructor(props) {
  super(props);
  this.imageRef = React.createRef();
}
.
.
<img ref={this.imageRef} src={urls.regular} alt={description} />
.
.
 2
3
4
5
6
7
8
9
Listening until images are loaded
componentDidMount() {
  this.imageRef.current.addEventListener("load", this.setSpans);
}
 2
3
# Redux vs Vuex
Flux libraries are like glasses : you'll know when you need them -Dan Abramov
In the past it was not uncommon to have pieces of state across our application tucked inside of controllers, services, routes, directives (AngularJS), local storage, session storage, cookies, and some other alternatives.
When the application grows, this approach is really hard to scale and this is where Flux and React stepped in.

Flux is the architectural pattern on which the Redux and later Vuex (with some diffs) were based. Flux assumes unidirectional data flow, while MVC is based on bidirectional flow.
An Action consists of action type and eventually action payload, that is the data that will be propagated to the store.
Dispatcher takes an action and dispatches it to a store, which updates themself and propagates a change event to views.
The Store is a “single source of truth” - it’s a global state of our application. It's the central point of the Flux pattern, where data are stored and passed to all components.
View is usually the component
The main difference between them - while Redux uses reducers Vuex uses mutations. In Redux state is always immutable, while in Vuex committing mutation by the store is the only way to change data
React is different from Vue in the way it processes updates: React renders a virtual DOM then calculates optimal DOM operations to make the currently rendered DOM match the new Virtual Dom. But it has no way of knowing whether a particular component needs to re-render or not based on the new data. Vue instances keep track of which bits of data they depend on to render. These instances automatically register what needs to re-render when the data changes.