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