REACT INTRODUCTION

What is React?

React is a JavaScript library and a tool for building UI components
React is also referred as a frontend JavaScript framework
React is created and maintained by Facebook

How does React work?

React uses a syntax extension of JavaScript called JSX (JavaScript XML) that allows user to write HTML directly within JavaScript
It lets user use the full programmatic power of JavaScript within HTML, and helps to keep the code readable
Instead of manipulating the browser's DOM directly, React creates a virtual DOM in memory
The virtual DOM does all the necessary manipulating, before making the changes in the browser DOM
The rendering API then places the JSX into React's own lightweight representation of the DOM
React then uses snapshots of its own DOM to optimize updating only specific parts of the actual DOM
For instance, because JSX is a syntactic extension of JavaScript, user can actually write JavaScript directly within JSX
To do this, simply include the code that want to be treated as JavaScript within curly braces "{}"

React component architecture

Components are the core of React
Since a JSX component represents HTML, user could put several components together to create a more complex HTML page
It allows user to compose the UI from many separate, isolated components
To compose multiple components together, user creates a parent component which renders each of other components as children
To render a component as a child in a React component, user include the component name written as a custom HTML tag in the JSX
User can render JSX elements, stateless functional components, and ES6 class components within other components
When React encounters a custom HTML tag that references another component, it renders the markup for that component in the location of the tag
This makes it easier to build and maintain complex user interfaces

React rendering API

JSX is a convenient tool to write readable HTML within JavaScript
ReactDOM provides a simple method to render React elements to the DOM → ReactDOM.render(componentToRender, targetNode);
The first argument is the React element or component that user want to render
The second argument is the DOM node that user want to render the component to
ReactDOM.render() must be called after the JSX element declarations

JSX Comment

Like most programming languages, JSX has its own way to add comments to the code for readability
JSX Comment Syntax → {/* MyComments */}

Self-Closing JSX Tag

In JSX, any JSX element can be written with a self-closing tag, and every element must be closed
For example, the <br> tag must always be written as <br /> in order to be valid JSX that can be transpiled
A <div>, on the other hand, can be written as <div /> or <div></div>
The difference is that in the first syntax version there is no way to include anything in the <div />

JSX Class

One key difference in JSX is the usage of class attribute which defines HTML classes
Since user can writing JavaScript code within JSX, the keyword class is invalid
This is because class is a reserved word in JavaScript, instead JSX uses className
In fact, the naming convention for all HTML attributes and event references in JSX become camelCase
HTML → JSX
class → className
onclick → onClick, onchange → onChange, etc.

JSX Style

User can import styles from a stylesheet
Then, user can apply a class to the JSX element using the className attribute, and apply styles to the class in the stylesheet
Another option is to apply inline styles, which are very common in ReactJS development
Invalid JSX
JSX elements use the style attribute, but since the way JSX is transpiled, it cannot set equal to JavaScript string
<div style="myProperty1: myValue1; myProperty2: myValue2;"> My JSX Contents </div>
Valid JSX
Instead, set it equal to JavaScript object
<div style={{myProperty1: myValue1, myProperty2: myValue2}}> My JSX Contents </div>
Hyphenated words like font-size are invalid syntax for JavaScript object properties, so React uses camelCase
As a rule, any hyphenated style properties are written using camel case in JSX
All property value length units (like height, width, fontSize) are assumed to be in px unless otherwise specified
<div style={{height: 20}}> myText </div> is the same as <div style={{height: "20px"}}> myText </div>

JSX ELEMENT

const MyJSXElement =
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
</div>;

ReactDOM.render(MyJSXElement, document.getElementById("myID"));

Simple JSX

The naming convention for a JSX element must applies PascalCase
Example
const MyJSXElement = <p> Hello World! </p>;

Complex JSX

One important thing to know about nested JSX is that it must return a single element
This one parent element would wrap all of the other levels of nested elements
If several JSX elements are written as siblings with no parent wrapper element, they will not be transpiled
Valid JSX
const MyJSXElement = (
<div>
<p> Paragraph 1 </p>
<p> Paragraph 2 </p>
<p> Paragraph 3 </p>
</div>
);
Invalid JSX
const MyJSXElement =
<p> Paragraph 1 </p>
<p> Paragraph 2 </p>
<p> Paragraph 3 </p>
When rendering multiple elements, user can wrap them all in parentheses, but it's not strictly required

STATELESS FUNCTIONAL COMPONENT

const MyComponent1 = (props) => {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
<MyComponent2 myProperty=myValue />
</div>
);
}

const MyComponent2 = (props) => {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
<div> {props.myProperty} </div>
</div>
);
}

MyComponent2.defaultProps = { myProperty: myDefault }

ReactDOM.render(<MyComponent1 />, document.getElementById("myID"));

What is Stateless Functional Component?

Stateless Functional Component is a component that defined with a JavaScript function which accepts props and returns either JSX or null
Stateless Functional Component can receive data and render it, but does not manage or track changes to that data
The naming convention for a function must applies PascalCase
JavaScript Function
const MyComponent = function() {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
</div>
);
}
ES6 Arrow Function
const MyComponent = () => {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
</div>
);
}
It is best practice to define stateless functional component with ES6 arrow function

props

myProperty=myValue → {props.myProperty}
The props stands for "properties"
User can use custom HTML attributes created by the user and supported by React to be passed to the component
It is standard to call this value props and when dealing with stateless functional components
Basically consider it as an argument to a function which returns JSX
User can access the value of the argument in the function body
Parent component passing props to child component
Number → <MyChildComponent myProperty={myNumber} />
String → <MyChildComponent myProperty={"myString"} />
Array → <MyChildComponent myProperty={[myData1, myData2]} />
Object → <MyChildComponent myProperty={myObject()} />
Child component access the props
Number, String, Object → <div> {prop.myProperty} </div>
Array → <div> {prop.myProperty.join(', ')} </div>

defaultProps

MyComponent.defaultProps = { myProperty: myDefault }
The defaultProps specifies what a prop value should be if no value is explicitly provided
The defaultProps can be assigned to a component as a property on the component itself and React assigns the default prop if necessary
React assigns default props if props are undefined, but if the component passed null as the value for a prop, it will remain null
The way to override the default props is to explicitly set the prop values for a component

PropTypes

import PropTypes from 'prop-types';
As of React v15.5.0, PropTypes is imported independently from React
Archive Documentations

STATELESS COMPONENT

class MyComponent1 extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
<MyComponent2 myProperty=myValue />
</div>
);
}
}

class MyComponent2 extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
<div> {this.props.myProperty} </div>
</div>
);
}
}

ReactDOM.render(<MyComponent1 />, document.getElementById("myID"));

What is Stateless Component?

Stateless Component is an ES6 class component that extends React.Component but does not use internal state
Stateless Component has access to many useful React features, such as local state and lifecycle hooks
Stateless Component must returns either JSX or null
The naming convention for an ES6 class must applies PascalCase

constructor() Method

The constructor() is a special method used during the initialization of objects that are created with the class keyword
Every stateless component has a constructor() defined within it that calls super()
The constructor() uses super() to call the constructor of the parent class, which is React.Component
It is best practice to call a component's constructor() with super(), and pass props to both
This makes sure the component is initialized properly

this.props

myProperty=myValue → {this.props.myProperty}

STATEFUL COMPONENT

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { myProperty: myValue };
}
render() {
return(
<div>
<div> My JSX Content 1 </div>
<div> My JSX Content 2 </div>
<div> {this.state.myProperty} </div>
</div>
);
}
}

ReactDOM.render(<MyComponent />, document.getElementById("myID"));

What is Stateful Component?

Statelful Component is an ES6 class component that does maintain its own internal state
Statelful Component must returns either JSX or null
The naming convention for an ES6 class must applies PascalCase

state

this.state = {myProperty: myValue}; → {this.state.myProperty}
Declaring a state property on the component class in its constructor will create a state in a React component
This initializes the component with state> when it is created and must be set to a JavaScript object
The advantage of using state is state consists of any data the application needs to know about, that can change over time
User have access to the state object throughout the life of the component
User can update it, render it in the UI, and pass it as props to child components
Advantages
state is one of the most powerful features of components in React
Once user define a component's initial state, user can display any part of it in the UI that is rendered
If a component is stateful, it will always have access to the data in state in its render() method
When a component stateful is created, no other components are aware of its state
Its state is completely encapsulated, or local to that component, unless user pass state data to a child component as props

this

this keyword is used by class method so it can access properties on the class (like state and props) inside the scope of the method
One common way is to explicitly bind this in the constructor so this becomes bound to the class methods when the component is initialized
Then, when user call a function like this.setState() within the class method, this refers to the class and will not be undefined

render()

render() {
My JS Codes;
return( My JSX Contents );
}
There is another way to access state in a component
In the render() method, before the return() statement, user can write JavaScript directly without inserting it inside of curly braces
This is because it is not yet within the JSX code
Example, user could declare functions, access data from state or props, perform computations on this data, etc.
Then, user can assign any data to variables, which user have access to in the return() statement

setState()

The setState() method allows user to update the component's state
React may batch multiple state updates in order to improve performance
In other words, the state updates through the setState() method can be asynchronous
Update state
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { myProperty: myInitialValue };
this.myEventHandler = this.myEventHandler.bind(this);
}

myEventHandler() {
this.setState( { myProperty: myUpdatedValue } );
}

render() {
return(
<div>
<button onClick={this.myEventHandler}> myButton </button>
<div> {this.state.myProperty} </div>
</div>
);
}
}
Toggle state
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { myVisibility: false };
this.myToggleHandler = this.myToggleHandler.bind(this);
}

myToggleHandler() {
this.setState(
state => {
if (state.myVisibility === true) {
return( { myVisibility: false } );
}
else {
return( { myVisibility: true } );
}
}
);
}

render() {
if (this.state.myVisibility) {
return(
<div>
<button onClick={this.myToggleHandler}> myButton </button>
<div> MyToggledText </div>
</div>
);
}
else {
return(
<div>
<button onClick={this.myToggleHandler}> myButton </button>
<div> MyInitialText </div>
</div>
);
}
}
}
Counter state
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { myCounter: 0 };
this.myIncrementHandler = this.myIncrementHandler.bind(this);
this.myDecrementHandler = this.myDecrementHandler.bind(this);
this.myResetHandler = this.myResetHandler.bind(this);
}

myIncrementHandler() {
this.setState(
state => ( { myCounter: state.myCounter + 1 } )
);
}

myDecrementHandler() {
this.setState(
state => ( { myCounter: state.myCounter - 1 } )
);
}

myResetHandler() {
this.setState( { myCounter: 0 } );
}

render() {
return(
<div>
<button onClick={this.myIncrementHandler}> myIncrementText </button>
<button onClick={this.myDecrementHandler}> myDecrementText </button>
<button onClick={this.myResetHandler}> myResetText </button>
<div> {this.state.myCounter} </div>
</div>
);
}
}
Controlled input
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { myInput: "" };
this.myInputHandler = this.myInputHandler.bind(this);
}

myInputHandler(event) {
this.setState( { myInput: event.target.value } );
}

render() {
return(
<div>
<input onChange={this.myInputHandler} value={this.state.myInput} />
<div> {this.state.myInput} </div>
</div>
);
}
}
Controlled form
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
myInput: "",
mySubmit: ""
};
this.myInputHandler = this.myInputHandler.bind(this);
this.mySubmitHandler = this.mySubmitHandler.bind(this);
}

myInputHandler(event) {
this.setState( { myInput: event.target.value } );
}

mySubmitHandler(event) {
event.preventDefault();
this.setState( { mySubmit: this.state.myInput } );
}

render() {
return(
<div>
<form onSubmit={this.mySubmitHandler}>
<input onChange={this.myInputHandler} value={this.state.myInput} />
<button type="submit"> myButton </button>
</form>
<div> {this.state.mySubmit} </div>
</div>
);
}
}

Passing state as props

myProperty={this.state.myProperty} → {this.props.myProperty}

Passing callback as props

User can also pass handler functions or any method that's defined on a React component to a child component
Simply pass methods to a child just like a regular prop
It's assigned a name and user have access to that method name under this.props in the child component

LIFECYCLE METHOD

What is Lifecycle Methods?

Lifecycle Methods (also known as Lifecycle Hooks) provide opportunities to perform actions at specific points in the lifecycle of a component
These methods allow user to catch components at certain points in time
This can be before they are rendered, before they update, before they receive props, before they unmount, and so on
componentWillMount()
The componentWillMount() method is called before the render() method when a component is being mounted to the DOM
The componentWillMount() method will be deprecated in a future version of 16.X and removed in version 17
Visit this source to learn more
componentDidMount()
componentDidMount() {
setTimeout(
() => { this.setState( { myProperty: myValue } ); },
2500
);
}
The componentDidMount() method specifies an API endpoint to place API calls or any calls to the server (to retrieve data)
This method is called after a component is mounted to the DOM
Any calls to setState() here will trigger a re-rendering of the component
When user call an API in this method, and set the state with the data that the API returns, it will automatically trigger an update once user receive the data
[NOTE] The 2500 stands for 2.5 seconds

[1] componentDidMount() method with Event Listener
The componentDidMount() method is also the best place to attach any event listeners user need to add for specific functionality
shouldComponentUpdate()
So far, if any component receives new state or new props, it re-renders itself and all its children
The shouldComponentUpdate() method specifies whether the components should update or not when receiving new state or props
This method is a useful way to optimize performance
componentDidUpdate()
componentWillUnmount()
[Follow up notes (1) from componentDidMount() method]
It's good practice to use componentWillUnmount() method to do any clean up on React components before they are unmounted and destroyed
Removing event listeners is an example of one such clean up action