React Hooks like am 5-ish: useEffect!

React Hooks like am 5-ish: useEffect!

TLDR:

The useEffect Hook executes whichever action (callback) as soon as the react components render. That's why it's used for things like data fetching, setting state etc ( these are side-effects, hence the name useEffect).

Into the details...

This is the third in a series of articles on React hooks, don't worry they are all standalone articles comparing certain commonly used hooks.

Have you heard of DOMContentLoaded event? This event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. That's what the MDN docs say and that's how I picture the useEffect hook, just so I can understand it more... Read more on Browser Events here: Intro to Browser Events

Here's a snippet from MDN:

window.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
});

// if you should run this snippet, 'DOM fully loaded 
// and parsed' will be written to console after every refresh.

Now let's put the same message in useEffect:

import React, {useEffect} from "react";

export default function App() {
useEffect( () => {
  alert('DOM fully loaded')
},[])
  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
    </div>
  );
}

// 'DOM fully loaded' as an alert should show up on your 
// screen as soon as the page is rendered.

Now let's talk about useEffect dependencies...

You can provide useEffect with conditions on which it should trigger, the conditions can be put in the dependency array. useEffect actually takes two arguments, a callback function and a dependency array, the dependency array means, a list of items to watch for changes and trigger rerenders..., Note that the dependency array is optional.

However, when the dependency array is empty, useEffect runs only on the initial render.

useEffect({
  console.log('call useEffect');
if (value >= 1) {
  document.title = "New messages";
}
// an empty dependency array means useEffect runs on the initial
// render, adding additional values mean that useEffect will run 
// whenever any of those values change.
}, []);
function ExampleComponent({id}) {
// In this snippet we have an effect hook with a callback
// function and then a dependency array with element 'id'
// this means useEffect will be watching for 'id' to change and trigger a rerender.
  useEffect(() => doSomething(id), [id]);
  return (<div></div>);
}

A DEEPER DIVE

According to the React Docs - (useEffect), The Effect Hook lets you perform side effects in function components. That is simple, but if you don't know what side effects are, you obviously don't understand this statement. So let's keep going...

What are side effects? Let me attempt an explanation with code...

// Consider the code below...

let someString = 'Improve';

function mergeStrings (stringArg) {
// mergeStrings reaches outside of this scope to access
// someString and use it in its operation.
  return stringArg + ' Specific Weaknesses';
}

console.log(mergeStrings(someString))

A side effect is when a function relies on, or modifies something outside its parameters to do something. When you start to write JS and progress into React or some other framework, you will find so many uses of this pattern. Here's a more technical definition from thejs.dev:

"A side effect is the modification of state through the invocation of a function or expression."

The preceding definition is more apt to the use cases of the useEffect hook in React, since that's exactly one of the typical instances of using the hook, For example: You have a state with an array object that should hold data returned from an API call as demonstrated below...

function Details() {
  const url = `some/URL`;

  const [data, setData] = useState([]);

// a typical case of side effect: 
  useEffect(() => {
// some API call
    axios
      .get(url)
      .then((response) => {
        console.log(response);
// setting state to the data
        setData( response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

And that's all for now... For further information on API, please check out the docs linked below, especially on Cleanup etc.

Thanks for reading... I encourage you to dive even deeper by reading any of the below articles which I found relevant to my understanding...

References & Resources for further reading: