Referential Equality And Usememo

[!INFO]-
topic: 🧩 React
links: Do not overuse useEffect
source: Top 6 React Hook Mistakes Beginners Make - YouTube
tags: #permanent-noteΒ #published

Last Modified: =dateformat(this.file.mtime, "MMM. dd, yyyy - HH:mm")


useMemo makes sure to update objects and arrays only when a property changes.

When a React component re-renders, it always renders a 100%. This also means, it initializes every const variable with new values.

This can trigger unwanted useEffect hooks because the object it watches get re-initialized, even though the values it contains are still the same.

Imagine some form to define a person that also has a toggle, that is unrelated to the person, e.g. a dark mode.

const [age, setAge] = useState(0);
const [name, setName] = useState("");
const [darkMode, setDarMode] = useState(false);

const person = {name, age}; // creates a new person on EVERY re-render

useEffect(() => {
	console.log(person); // this gets printed, event if you update darkMode, even though you didn't change person
}, [person]);

In the example above, a new person gets created, even when you toggle dark mode. This happens because the const person is re-created on every render.

In JavaScript, a new object is always different from the previous one, even if the values are the same. They are only equal, if the reference is equal (const personB = personA) This concept is called referential equality.

To avoid this, you can use the useMemo hook. It only updates a variable if a property really changes.

const [age, setAge] = useState(0);
const [name, setName] = useState("");
const [darkMode, setDarMode] = useState(false);

const person = useMemo(() => {
	return {name, age}; // only updates person when a property defined in the dependencies changes
}, [name, age]); //dependencies

useEffect(() => {
	console.log(person); 
}, [person]);