Important Topics from React & JavaScript
React Hooks
React hooks allow us to reuse stateful logic without changing the component hierarchy. Hoooks let us use more react's features without classes.
State Hook
useState()
is similar to this.setState in a class, except it doesn't merge the old and new state together.
import React, { useState } from "react"
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
Effect Hook
useEffect()
is used to handle the side effects (data fetching, subscriptions, or changing the DOM). Because these side effects can affect other components and can't be done during rendering.
By default, react runs the effects after every ender - including the first render.
Effects is also used to clean up after unmount of a component.
import React, { useState, useEffect } from "react"
export function EffectExample() {
const [count, setCount] = useState(0)
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`
}, [count]) // Only re-run the effect if count changes
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(prevCount => prevCount + 1)}>
Click me
</button>
</div>
)
}
Rules of Hooks
- Only Call Hooks at the Top Level
- Don’t call Hooks inside loops, conditions, or nested functions.
- If we want to run an effect conditionally, we can put that condition inside our Hook:
- Only Call Hooks from React Functions
- Don’t call Hooks from regular JavaScript functions.
import React, { useState, useEffect } from "react"
export function FormHooks() {
// 1. Use the name state variable
const [name, setName] = useState("Mary")
// 2. Use an effect for persisting the form
useEffect(function persistForm() {
localStorage.setItem("formData", name)
})
// 3. Use the surname state variable
const [surname, setSurname] = useState("Poppins")
// 4. Use an effect for updating the title
useEffect(function updateTitle() {
document.title = name + " " + surname
})
return <div></div>
}
Accessibility
Web accessibility (also known as a11y) support is necessary to allow assistive technology to interpret web pages.
React supports building accessible websites, by using standard HTML techniques.
Whereas most DOM properties and attributes in React are camelCased, aria-*
HTML attributes should be kebab-cased as they are in plain HTML.
<input type="text" aria-label={labelText} />
Global Context
In the global context, this refers to the global object. In browser, the global context is window
. In node.js, global context is global
.
// In a browser:
console.log(this === window) // true
// In node:
console.log(this === global) // true
Function Context
Inside a function, the value of this
depends on how the function is called.
In non-strict mode, if the value of this
is not set, this
will default to the global object.
function f() {
return this
}
// In a browser
f() === window // true
// In Node:
f() === global // true
In strict mode
, if the value of this
is not set, this
will be undefined
.
function f() {
"use strict"
return this
}
f() === undefined // true
To set value of this
to a particular value when calling a function, use call(), or apply()
Object Methods
An object method uses this
to refer to the properties of the object.
const address = {
name: "Foyez",
city: "Cumilla",
describe() {
console.log(`I'm ${this.name} from ${this.city}`)
},
}
address.describe() // I'm Foyez from Cumilla
Class Context
Note: Static methods are not properties of this. They are properties of the class itself.
Arrow functions
call()
& apply()
call and apply are very similar. The both method call a function with a given this
value and can pass optional arguments. The only difference is, call requires the arguments to be provided individually (one-by-one), and apply takes the arguments as an array (or an array-like object).
In this example, we'll create an object, and a function that references this but has no this context. However, we can use call
and apply
to invoke the this
context of address
on the function.
const address = {
name: "Foyez",
city: "Cumilla",
getAddress() {
console.log(`I live in beautiful ${this.city}.`)
},
}
function summary() {
console.log(`I'm ${this.name} from ${this.city}.`)
}
function longSummary(occupation, food) {
console.log(
`I'm ${this.name} from ${this.city}. I'm a/an ${occupation}. I love ${food}.`
)
}
summary() // I'm undefined from undefined
summary.call(address) // I'm Foyez from Cumilla
summary.apply(address) // I'm Foyez from Cumilla
const getAddress = address.getAddress
getAddress() // I live in beautiful undefined.
getAddress.call(address) // I live in beautiful Cumilla.
longSummary.call(address, "student", "mango") // I'm Foyez from Cumilla. I'm a/an student. I love mango.
longSummary.apply(address, ["student", "mango"]) // I'm Foyez from Cumilla. I'm a/an student. I love mango.
To set the value of this
to a particular value when calling a function, use call()
, or apply()
as in the examples below.
bind()
The bind()
method creates a new function with an explicitly bound this
.
bind()
method is used in place of call()
and apply()
when we need to use the function bounded with this
over and over.
const address = {
name: "Foyez",
city: "Cumilla",
getCity: function () {
return this.city
},
}
function summary() {
console.log(`I'm ${this.name}. I'm from ${this.getCity()}.`)
}
const unboundGetCity = address.getCity
console.log(unboundGetCity()) // undefined
const boundGetCity = unboundGetCity.bind(address)
console.log(boundGetCity()) // Cumilla
const boundedSummary = summary.bind(address)
boundedSummary() // I'm Foyez. I'm from Cumilla.