Hooks were introduced in 2018. Nowadays hooks are everyday tools for developers, at least for those developers working with the code base using functional components. When i first started building functional React apps i didn't have any idea how to use custom hooks and most of the hooks i was using was useState and useEffect and due to that probably filled the codebase with alot of repeated non-sense.
React Hooks
So what are React Hooks ? They can be stateful and manage side-effects. React Hooks are simple functions that we can use to separate the reusable code from a functional component. In short, hooks opens up stateful logic for reusability without the change of component hierarchy.
There are roughly five categories of hooks.
- State management, such as useState which is for storing information such as user input value.
- Reference creating, such as useRef. Here is my article about useRef hook.
- Effects. These hooks let you deal with DOM, animations, networks and such. Shortly useEffect lets you haves side effects inside your functional component which is convinient because React is heavily leaning towards pure components.
- Context. useContext is used for receiving information from other components without passing props.
- Performance improvement hooks such as useMemo. useMemo is used to reduce unnecessary re-rendering if data didn't change since previous rendering.
React Custom Hooks
So now we covered some basics of hooks, what are the custom hooks then ? Custom hooks are reusable functions but in React way. Reason is the same as with any reusable functions to reduce repeating your code.
Naming function naming should be starting with word "use" such as useSettings or useInput. Custom hooks should only be called inside functional component body but not inside for loops, conditions or nested functions but you can call them inside other custom hooks.
Example
Here is just an sample to show structure of simple custom hook. Our hook name is useUserStatus and we are using React internal hook useState and useEffect handling state and effects.
function useUserStatus(uid) { const [isOnline, setIsOnline] = useState(false); useEffect(() => { // useeffect logic }, []); if (uid) { setIsOnline(true); } // ... other logics return { isOnline, otherLogic }; }
Here is example using ref for counting inside custom hook.
import { useRef, useState } from 'react'; const useCounter = (amountOfClicks) => { const count = useRef(0); const [contented, setIsContented] = useState(false); const next = () => { if (count.current >= amountOfClicks) { return; } count.current = count.current + 1; if (count.current === amountOfClicks) { setIsContented(true); } }; return { count: count.current, contented, next }; }; export default useCounter;
and the way you would use this kind of hook is something like this.
import useCounter from './useCounter'; function App() { const amountOfClicks = 10; const { count, contented, next } = useCounter(amountOfClicks); return ( <div className="App"> <header className="App-header"> <p style={{ color: contented ? 'green' : 'red' }}> <code>{count}</code> </p> <button disabled={contented} onClick={next}> click to add </button> </header> </div> ); } export default App;
Here we have sample how to use custom hook. In this sample, we pass amountOfClicks to our hook, this is cap it takes to re-render your page and change conditions. In this case if contented is true background changes to green and count to 10 and button is disabled.
Conclusion
When you are working day to day development you should consider adapting custom hooks as part of your toolkit, using custom hooks can reduce repeating code and keep your codebase cleaner.