/
๐Ÿ˜‚

React Hook Pitfalls

https://www.lorenzweiss.de/common_mistakes_react_hooks/
ReactHookPitfall
Table of contents

List some common use hooks pitfall here.

Using useState when no rerender is needed

Should not ๐Ÿ™…๐Ÿฝ
jsx
function ClickButton(props) {
const [count, setCount] = useState(0);
const onClickCount = () => {
setCount((c) => c + 1);
};
const onClickRequest = () => {
apiCall(count);
};
return (
<div>
<button onClick={onClickCount}>Counter</button>
<button onClick={onClickRequest}>Submit</button>
</div>
);
}

Should ๐Ÿ‘

jsx
function ClickButton(props) {
const count = useRef(0);
const onClickCount = () => {
count.current++;
};
const onClickRequest = () => {
apiCall(count.current);
};
return (
<div>
<button onClick={onClickCount}>Counter</button>
<button onClick={onClickRequest}>Submit</button>
</div>
);
}
Should not ๐Ÿ™…๐Ÿฝ
jsx
function ClickButton(props) {
const history = useHistory();
const onClick = () => {
history.push("/next-page");
};
return <button onClick={onClick}>Go to next page</button>;
}

Should ๐Ÿ‘

jsx
function ClickButton(props) {
return (
<Link to="/next-page">
<span>Go to next page</span>
</Link>
);
}

Handling actions via useEffect

Should not ๐Ÿ™…๐Ÿฝ

jsx
function DataList({ onSuccess }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
const fetchData = () => {
setLoading(true);
callApi()
.then((res) => setData(res))
.catch((err) => setError(err))
.finally(() => setLoading(false));
};
useEffect(() => {
fetchData();
}, []);
useEffect(() => {
if (!loading && !error && data) {
onSuccess();
}
}, [loading, error, data, onSuccess]);
return <div>Data: {data}</div>;
}

Should ๐Ÿ‘

jsx
function DataList({ onSuccess }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
const fetchData = () => {
setLoading(true);
callApi()
.then((fetchedData) => {
setData(fetchedData);
onSuccess();
})
.catch((err) => setError(err))
.finally(() => setLoading(false));
};
useEffect(() => {
fetchData();
}, []);
return <div>{data}</div>;
}

Single responsibility components

Should not ๐Ÿ™…๐Ÿฝ

jsx
function Header(props) {
return (
<header>
<HeaderInner menuItems={menuItems} />
</header>
);
}
function HeaderInner({ menuItems }) {
return isMobile() ? (
<BurgerButton menuItems={menuItems} />
) : (
<Tabs tabData={menuItems} />
);
}

Should ๐Ÿ‘

jsx
function Header(props) {
return (
<header>
{isMobile() ? (
<BurgerButton menuItems={menuItems} />
) : (
<Tabs tabData={menuItems} />
)}
</header>
);
}

Single responsibility useEffects

Should not ๐Ÿ™…๐Ÿฝ

jsx
function Example(props) {
const location = useLocation();
const fetchData = () => {
/* Calling the api */
};
const updateBreadcrumbs = () => {
/* Updating the breadcrumbs*/
};
useEffect(() => {
fetchData();
updateBreadcrumbs();
}, [location.pathname]);
return (
<div>
<BreadCrumbs />
</div>
);
}

Should ๐Ÿ‘

jsx
function Example(props) {
const location = useLocation();
const updateBreadcrumbs = () => {
/* Updating the breadcrumbs*/
};
useEffect(() => {
updateBreadcrumbs();
}, [location.pathname]);
const fetchData = () => {
/* Call the api */
};
useEffect(() => {
fetchData();
}, []);
return (
<div>
<BreadCrumbs />
</div>
);
}
Kelvin's Tech Notes