Skip to main content

React useEffect

Provides us an opportunity to write code that may have side effects on the application.

Examples use cases

  • Fetching Data
  • Logging
  • Subscriptions
  • Mutations
warning

Most common cause of confusion

Double Call Explanation

React Strict Mode

  1. Always specifify a dependency array
  2. Check that items in the dependency array are primitive values
  3. If dependency items is an array, function, or object, will need to memoize the value

See taming useEffect

useLayoutEffect

  • useEffect is async and runs after the browser has painted
  • useLayoutEffect is sync and runs before the browser has painted

If a component seems to flicker when the state is updated you should use useLayoutEffect.

  • Render computing the styles for each DOM node
  • Paint content to be displayed/updated on the screen

The reason for the flicker is because the callback is making visual changes to the DOM right after the component is painted.

If you need to update a ref value before any other code runs, use useLayoutEffect.

const ref = React.useRef();
React.useEffect(() => {
ref.value = 'some value';
});
// then, later in another hook or something
React.useLayoutEffect(() => {
console.log(ref.value); // logs old value as this runs first!
});

Snippets

useFetch

import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';

const useCallbackRef = (callback) => {
const callbackRef = useRef(callback);
useLayoutEffect(() => {
callbackRef.current = callback;
}, [callback]);
return callbackRef;
};

export const useFetch = (options) => {
const [data, setData] = useState(null);

const savedOnSuccess = useCallbackRef(options.onSuccess);

useEffect(() => {
console.log('useFetch useEffect ');
if (options.url) {
let isCancelled = false;
fetch(options.url)
.then((response) => response.json())
.then((json) => {
if (!isCancelled) {
savedOnSuccess.current?.(json);
setData(json);
}
});
return () => {
isCancelled = true;
};
}
}, [options.url]);

return {
data,
};
};