#1 Manage state
Use the useReducer
and useState
hooks to manage state in functional components.
useState
const [count, setCount] = useState(initialCount);
Class way
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: initialCount };
}
render() {
return (
You clicked {this.state.count} times
);
}
}
Hook way
import { useState } from "react";
const initialCount = 0;
function Counter() {
const [count, setCount] = useState(initialCount);
return (
You clicked {count} times
);
}
#2 Handle side effects
Use the useEffect
and useLayoutEffect
hooks to handle side effects in functional components.
useEffect
import { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
const handleStatusChange = (status) => setIsOnline(status.isOnline);
useEffect(() => {
// Subscribe to status changes
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Cleanup subscription
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
}, [props.friend.id]); // Cleanup when friend id changes
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
useLayoutEffect
import { useRef, useLayoutEffect } from "react";
function ColoredComponent({ color }) {
const ref = useRef();
useLayoutEffect(() => {
const refColor = ref.current.style.color;
console.log(`${refColor} will always be the same as ${color}`);
ref.current.style.color = "rgba(255,0,0)";
}, [color]);
useEffect(() => {
const refColor = ref.current.style.color;
console.log(`but ${refColor} can be different from ${color} if you play with the DOM`);
}, [color]);
return (
Hello React hooks !
);
}
#3 Use the Context API
Use the useContext
hook to access values from context directly in functional components.
Class way
class Header extends React.Component {
render() {
return (
{({ handleLogin, isLoggedIn }) => (
{({ isOpen, showModal, hideModal }) => (
{({ notification, notify }) => {
return (
// Content here
);
}}
)}
)}
);
}
}
Hook way
import { useContext } from 'react';
function Header() {
const { handleLogin, isLoggedIn } = useContext(AuthContext);
const { isOpen, showModal, hideModal } = useContext(ModalContext);
const { notification, notify } = useContext(NotificationContext);
return (
// Content here
);
}
#4 Memoize everything
Use the useMemo
and useCallback
hooks to memoize expensive functions and callbacks.
useMemo
const memoizedValue = useMemo(() => expensiveFn(dependencies), [dependencies]);
useCallback
const memoizedCallback = useCallback(expensiveFn(dependencies), [dependencies]);
#5 Use refs
Use the useRef
hook to persist values between renders without causing a re-render.
import { useRef } from "react";
function TextInput() {
const inputRef = useRef(null);
const onBtnClick = () => inputRef.current.focus();
return (
<>
>
);
}
#6 Reusability
Make components more reusable by extracting logic into custom hooks.
function useHover() {
const [value, setValue] = useState(false);
const ref = useRef(null);
const handleMouseOver = useCallback(() => setValue(true), []);
const handleMouseOut = useCallback(() => setValue(false), []);
useEffect(() => {
const node = ref.current;
if (node) {
node.addEventListener("mouseover", handleMouseOver);
node.addEventListener("mouseout", handleMouseOut);
return () => {
node.removeEventListener("mouseover", handleMouseOver);
node.removeEventListener("mouseout", handleMouseOut);
};
}
}, [ref.current]);
return [ref, value];
}
const HoverableComponent = () => {
const [ref, isHovered] = useHover();
return (
Hello React hooks!
);
};
Labels
Development