We Might Not Need an Effect #1

RMAG news

What this article series are about 🔍

This article series are basically a summary of You Might Not Need an Effect, which is a React official documentation about the usage of useEffect hook in React.

The original article is really really good, for sure better than my summary. So, if you have time, I highly recommend you to read the original article.

My motivation is just to provide a quick summary both for myself and for others who might be busy or a bit lazy to read through the whole article.

Yeah, it’s for you 😉 haha

I summarized the content as short as possible, so we can get main idea quickly.
So don’t forget to check the original article for more detailed information. Again, it’s really good learning material.

When something can be calculated from the existing props or state, we don’t need extra state and useEffect

Bad 👎

function Form() {
const [firstName, setFirstName] = useState();
const [lastName, setLastName] = useState();

// 🔴 Unnecessary extra state and useEffect
const [fullName, setFullName] = useState();
useEffect(() => {
setFullName(firstName + + lastName);
}, [firstName, lastName]);
//

return (
<div>
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
placeholder=“First Name”
/>
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
placeholder=“Last Name”
/>
<h1>{fullName}</h1>
</div>
);
}

Good 👍

function Form() {
const [firstName, setFirstName] = useState();
const [lastName, setLastName] = useState();

// ✅ No extra state and useEffect
const fullName = firstName + + lastName;

return (
<div>
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
placeholder=“First Name”
/>
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
placeholder=“Last Name”
/>
<h1>fullName</h1>
</div>
);
}

Takeaway

The point is to let re-render do the calculation, instead of doing it with extra state and useEffect.
When we call setFirstName or setLastName, we trigger a re-render, and then the next fullName will be calculated from the fresh data.

Reference

Updating state based on props or state
Avoid redundant state

When we use useEffect just to update something only when some props or state is updated, what we really need is useMemo.

Bad 👎

getFilteredTodos is a function that filters todos based on the filter, and it is used to calculate visibleTodos.
Maybe you want to update visibleTodos only when todos or filter changes.

function TodoList({ todos, filter }) {
const [newTodo, setNewTodo] = useState();

// 🔴 Unnecessary extra state and useEffect
const [visibleTodos, setVisibleTodos] = useState([]);
useEffect(() => {
setVisibleTodos(getFilteredTodos(todos, filter));
}, [todos, filter]);

}

Good 👍

function TodoList({ todos, filter }) {
const [newTodo, setNewTodo] = useState();

// ✅ No extra state and useEffect, but efficient use of useMemo
const visibleTodos = useMemo(
() => getFilteredTodos(todos, filter),
[todos, filter]
);
}

Takeaway

If your motivation to use useEffect is just to update something only when some props or state is updated, what you really need is useMemo.

Reference

Caching expensive calculation

When we want to reset the state based on some prop change, we could do it witout useEffect

Bad 👎

function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selectedItem, setSelectedItem] = useState(null);

// 🔴 Avoid: resetting state on prop change in an Effect
useEffect(() => {
setSelection(null);
}, [items]);
// …
}

Good 👍

function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
// Change selectedItem to selectedItemId, so that we don’t need to reset state on prop change
const [selectedItemId, setSelectedItemId] = useState(null);

// ✅ No extra state and useEffect, just calculate selectedItem when selectedItemId changes
const selectedItem = useMemo(items.find((item) => item.id === selectedItemId);,[items, selectedItemId]);
}

Takeaway

When you adjusting or resetting the state based on some prop change, you better to think about the way to do it without useEffect

Reference

Adjusting some state when a prop changes

See you again in #2 !

Leave a Reply

Your email address will not be published. Required fields are marked *