• useEffectReact Hooks — Part 2

📄 Table of Contents

▬▬▬▬▬▬▬▬▬▬▬▬▬ ✦ ✦ ✦ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

A key difference between class and functional components is the fact that class components have a state (stateful) while functional components are stateless.

Stateless components do not use the “this” keyword.

Reminder: React first updates the DOM i.e., goes inside return statement, and then it calls any function that is passed into useEffect().

Class component showing how to use this.setState
Functional component showing how to use useState

➪ Using useRef As useState Replacement

You might know useRef as a tool to reference native DOM elements in order to focus on an input or to perform other similar DOM interactions. — but that’s NOT the only thing you can do with it.

Snippet of example usage from React docs:

function TextInputWithFocusButton() {  const inputEl = useRef(null);  const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
}; return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}

useRef can be used as an alternative to useState or useReducer.

The difference: Whenever its value changes, it does NOT force a render cycle. Therefore, in many typical cases of React development, useState is already a good choice — yet, in some, for example, the above one, useRef is much better.

Here is how to use it.

Translating a useState example to useRef

After importing useRef similar to the other hooks:

import { useRef } from "react"

Instead of using the destructuring syntax and getting a function for changing the state out of it, we treat useRef like a normal object.

Compared to useState, the console.logs do no longer appear whenever we type something into the input. Nevertheless, the value is actually there — the React dev tools provide us with evidence:

Summing up

If you want to have state in your components, that triggers a rerender when changed, go with useState or useReducer. If you do not want to have state, triggering a rerender, go with useRef.

For more @ https://medium.com/codex/usestate-useref-react-9f2398606d51

➪ useMemo and useCallback

Both of these hooks are similar in that they are used to memoize.

The main difference is that useMemo can be used to memoize any value including functions, while useCallback can only be used to memoize functions.

➪ useState()

The useState hook is a special function that lets us add state to a function component. The useState hook takes an initial value and returns a stateful value and a function to update it.

In classes, the state is always an object, but with hooks, the state is not necessarily an object, it can be of any type.

Syntax:

With useState hook the initial value of the state, the method to update the state, and the current value of the state everything can be written in a single line of code.
This syntax is known as
Array Destructuring which is one of the features of ES6.

useState with the previous value of state

Sometimes we need to access the previous value of the state to update the current state, this can be done by passing a function to useState in the previous example. This function will have access to the previous value, and return an updated value.

Here’s an example of a counter component that updates the state using useState hook with the previous value of the state

useState with Object

Now we’ll see another example that makes use of the useState Hook when our State is an Object. Let’s try to print the full name of a person, based on values entered in the firstName and LastName field.

We’ll take values from the state and update it onChange of input fields.

In the above example, the state object is holding firstName and lastName properties, and these values are updated as soon as the user enters something in the input field.

Now, you might have noticed that we are merging states inside the onChange function using the spread operator with fullName i.e. {…fullName}. It is because unlike setState() the useState hook doesn’t automatically merge state objects. Hence we have to do manual merge by using a Spread Operator as you can see in the above example.

When dealing with Objects or Arrays, always make sure to spread your state variable and then call the setter function

➪ useEffect

Class component demonstrating the use of lifecycle methods

While viewing the page, let’s say you chose the button that says “RED.” componentDidUpdate is then invoked. The terminal will now print out “The component was updated!” followed by “RED.” If you decide to choose the blue button, componentDidUpdate will be invoked again, as it would be each time you chose a different button. componentDidUpdate is executed any time the component has re-rendered.

How can we do this in a functional component?

Functional component showing an example of using useEffect

When we first used the useEffect hook to mimic componentDidMount, we passed an empty array as the second argument. Because there is an empty array in the second argument, this string will no longer be logged to the console during if the component is rendered again. To mimic componentDidUpdate, we will add the dependency in an array as the second argument.

For running useEffect conditionally we need to pass an additional parameter which is an array. In this array, we specify either prop or state which we need to watch for. Then this function will be executed only if those states or props are updated.

If you want to run useEffect only on the component mount, you can pass an empty array instead of passing any prop or state.

To perform any action on component unmount using useEffect hook, the function that is passed to useEffect can return another function that will be executed when the component will unmount. So, whatever we return is a cleanup function.

➪ useReducer

useReducer is more performant than useState in the example above since we’re replacing multiple useState calls (which can cause multiple re-renders) with one useReducer call.

The difference in performance is not significant enough for this to be a concern, but it is worth noting that there is a slight performance benefit to taking the useReducer approach in similar scenarios.

Check out the two different implementations below for the getUsers() function and decide for yourself which is clearer.

useReducer implementation:

function usersReducer(state, action) {
switch (action.type) {
case "LOADING": {
return { loading: true, users: null, error: null };
}
case "LOADED": {
return { loading: false, users: action.users, error: null };
}
case "ERROR": {
return { loading: false, users: null, error: action.error };
}
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
}
function UsersList() {
const [state, dispatch] = React.useReducer(usersReducer, {
users: null,
loading: false,
error: null
});
function getUsers() {
dispatch({ type: "LOADING" });
fetchUsers().then(
users => {
dispatch({ type: "LOADED", users });
},
error => {
dispatch({ type: "ERROR", error });
}
);
}
}

useState implementation:

function UsersList() {
const [users, setUsers] = React.useState(null);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState(null); function getUsers() {
setLoading(true);
setError(null);
setUsers(null); fetchUsers().then(
users => {
setLoading(false);
setError(null);
setUsers(users);
},
error => {
setLoading(false);
setError(error);
setUsers(null);
}
);
}
}➪ useContext

➪ useContext

useContext is helpful any time you need to pass a prop through many nested children (to solve the prop-drilling problem), or when you need global state.

In the example below, even though we didn’t pass any props to the RandomNumber or NumberGenerator components, they can still access the necessary props through RandomNumberContext.

for more @ https://medium.com/in-the-weeds/an-intro-to-advanced-react-hooks-a8af6397fe28

➪ useLayoutEffect

A notable change from class components to hooks is that componentDidMount and componenentDidUpdate fires before the UI is painted while useEffect fires after the UI is painted. Why is this the new default? You may have code in useEffect that can take a while, like an expensive call to the server, or a call to a third party service that shouldn’t block the UI from displaying content to the user.

If you want the previous behavior (of firing useEffect before the UI is painted) that's where useLayoutEffect comes in.

The only time you need this is when you have code within useEffect that has an observable visual effect — for example, when you are scrolling to the bottom of a window or when you are resizing an element. If you find that the UI is jumping around based on code in useEffect, try replacing useEffect with useLayoutEffect.

➪ useQuery

Here we will be going over an example of how to implement the “useQuery” hook starting with installing this dependency “Axios”.

Now that we have Axios installed here is an example of a React.js file. It uses React-Query to import the “useQuery” hook, as well as Axios, so we can fetch the data that we need.

source: https://johnnie-agonz71.medium.com/using-reacts-usequery-hook-to-fetch-data-cf25ee334f25

References:

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.