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); // trueFunction 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; // trueIn strict mode, if the value of this is not set, this will be undefined.
function f() {
"use strict";
return this;
}
f() === undefined; // trueTo 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 CumillaClass 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.