React training
===
**IDE**
Visual Studio Code
### General intro
- JS framework with HTML contained within JS
- Single index.html is close to empty and index.js will inject everything into the HTML file. --> Single Page App.
- index.js executes the scripts and contents in package.json
- Top-down structure. One element comes from the top of the container and goes down its components.
### Redux
- Unlike a component, a *container* is used by Redux to pass information. The containers are React components connected to the Redux "store" which contains variables
- All redux files are in /store. A store = a subgroup of variables.
- Structure:
- Breakdown by concept / theme (eg dashboard, company...) -- 1 theme = 1 folder. Contains 2 JS files:
- actions.js = they specify the properties of the HTTP request to be made (endpoint, body, method type...) and will call methods within middleware.js
- reducers.js = once an action is executed, the reducer takes the data that is returned and formats it to be stored then returns it. Reducers have to be "pure" (no side effects, no API calls, business logic, etc.).
- The reducer contains its initial state (usually a bunch of null values)
- Then a method with specific arguments is defined: `const whatever = (state = initialState, action)`. This method will catch all actions and we can use a `switch` statement to act upon the ones related to the specific reducer, eg:
`const dashboard... switch (action.type) {case 'GET_DASHBOARD:SUCCESS' } ...`
- The action argument is a specific object which contains properties .type (action keyword) and .payload (object returned by the action)
- The dispatch function: used by redux-thunk to make asynch API calls
### Components
**Component lifecycle**
--> For each step of its lifecycle, the component will execute specific JS functions (such as useEffect) which we can customize
- willMount()
- didMount() = DOM insertion
- render()
- willUnmount()
- didUnmount()
- didUpdate() = Props change
- ...
Can't do:
const Comp = () =>
**Component styling lib: ant.design**
- ant.design is a lib that contains UI components that can be re-used and customized
**Variable injection within components**
```
const x = (name) => (
<MyComponent>{name}</MyComponent>
)
```
`x()` Will return a component containing the name in arg
**Injecting components within components**
Imagine we want to list some bullet points within a higher-level component
```
const Item = (props) => {
const text = props.text
return (
<li>{text}</li>
)}
const itemTexts = ["Bullet point 1", "Bullet point 2"]
const ItemList = () => (
<ul>
itemTexts.map((text, i) => (
<Item text={text} />
))
</ul>)
```
Upon rendering we're going to end up with:
```
<ul>
<li>Bullet point 1</li>
<li>Bullet point 2</li>
</ul>
```
Components need to have only one tag at the top level. If we hadn't needed `<ul>` or `<div>` we could have used `<Fragment>` instead
**Two ways to define components: functions vs classes**
As a class:
```
import React, {Component} from react
class BasicButton extends Component {
// Equivalent of the useEffects hook
componentDidMount() {
// Do something
}
// Called after mounting and after state changes.
render() {
// Here we destructurate name (props.name)
const { name } = this.props
return <div>{name}</div>
}
}
export default BasicButton
```
As a function:
```
const Button = (props) => {
const {name} = props
return (
<div>{name}</div>
)
}
export default Button
```
**Styling using Emotion**
Let's say that we want our button above to have a red background.
In another file `style.jsx`:
```
import styled from "emotion/styled/macro"
// Note the use of a backtick at the end of the line
export const StyledButton = styled.div`
background-color: "red"
`
index.jsx
import {StyledButton} from '../styles.jsx'
class BasicButton extends Component {
render() {
// Here we destructurate name (props.name)
const { name } = this.props
return <StyledButton>{name}</StyledButton>
}
}
```
**How API calls / rendering works in our app**
- The component is rendered then the hook useEffect() is used to populate the component / HTML
- The useEffect calls props.getData() = Redux action
- Within Redux (/store), ...
### Syntax
**Different syntaxes to define functions**
```
function x(a) {
return 1
}
const x = (a) => {
return 1
}
const x = a => getDashboard(a)
```
**Simplified if/else**
```
const test = function() {
if (x == 1) {
return true
}
else {
return false
}}()
```
Is the same as:
```const test = x == 1 ? false : true```
Difference between == and ===
`==` makes implicit conversions. For instance:
- null == undefined returns true
- null === undefined return false
It is best to never use ==, instead always use === to avoid implicit conversion sides effects
**Spead operators**
```state = {
"a" : 1,
"b" : 2
}
x = {
state,
"c" : 3
}
```
is equivalent to:
```
{
{
"a" : 1,
"b" : 2
},
"c" : 3
}
```
whereas:
```
x= {
...state,
"c" : 3
}
```
is equivalent to:
```
{
"a" : 1,
"b" : 2,
"c" : 3
}
```
**[Destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)**
```
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20
// Stage 4(finished) proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
```
In normal syntax, we would have said:
```
x = {
a: 10,
b: 20
}
b = x.b
```
**Arrow syntax**:
"Old" way of defining anonymous functions:
```const x = function(arg){
return arg
}
x(1)
>>> 1
```
is equivalent to
```
const x = (arg) => {
return arg
}
x(1)
>>> 1
```
```
const x = arg => arg
```
Example of short anonymous function with map
```
const myArray = [1, 2, 3]
const mapped = myArray.map(elem => (elem+1))
console.log(mapped)
>>> [2, 3, 4]
```
Note we can also enumerate with map, just add i as an argument: (elem, i)
**Formatted strings**
```
const x = (name, age) => `${name} is ${age} years old`
console.log(x("Antoine", 26))
>>> "Antoine is 26 years old"
```