Agenda
- What is Hooks
- Purpose of Hooks
- Hooks — to manage model state
- Hooks — to manage logic of model state
- Rules of Hooks
- Other Hooks
- Conclusion
What is Hooks
Hooks is a feature, which helps developer to manage or hold the logic of the state inside functional component.
In React, we write two types of component, they are
- Functional — Component which is stateless [just like JavaScript Function without side effects (aka. pure function]
- Class — Component which manages the state + manage the logic of the state that has to be driven in the respective stages of the component initialization (i am pointing to life cycle interception)
Before Hooks — It’s must, to use class component - if we need to manage an internal state.
Hooks is a discovery rather than invention
Purpose of Hooks
Class component solves the problem already, but why Hooks? Answers is.
- Difficult in understanding this which roam inside a class. If we have to use class method call from the event handlers of an element
<a onClick={callingClassMethod}></a>
we have to bind this with thecallingClassMethod
in the constructor otherwise we have few other options buts it need more understanding on how this works in JavaScript. - With class component, we can maintain the logic of handling state that will be grouped by life-cycle methods (
componentDidMount
,componentWillUnmount
) rather than feature wise (For e.g. — streamsubscribing,
unsubscribing
). It brittle the testing part. - Its hard to reuse the logic of managing the state. —However we can use higher order, render prop strategies to reuse, but still Hooks makes it simplest.
Hooks — to manage model state
Lets see some hooks which helps to persist the data model inside the component.
- useState — Hook helps to manage primitive data, of-course you can manage complex model like object, array but
useReducer
is recommended for that. - useReducer — Hook helps to manage complex model like object, array — the pattern is similar to Reducer in Redux
(state, action) => state
useState
In the example above — We have used useState
hook, which accepts initial state or fat function which returns initial state as an argument.
We are using de-structuring here — means useState returns an array where
- first array element (
count
)— is data - second array element (
setCount
) — is method to update the data
useState hook will not merge your update while managing the complex state.
Thanks to Chidume Nnamdi 🔥💻🎵🎮 for bringing this point to the community.
In class component, when we use this.setState
to partially update the complex state i.e — this.setState({password: this.value})
then if username property holds an value already, that will be retained.
useReducer
If you see the state or data we managed in the sample above — was collection (Array) of todo
objects, so we have used useReducer
which accepts reducer function (function with signature (state, action) => state
) and initial state.
useReducer
has optional third argument where we can pass initial action to the reducer while initiated.
In our example — ToDos
component has many other components like TodoList
, TodoForm
, Todo
with-in its tree. In this kind of scenario — React team recommend to pass down a dispatch
function from useReducer
via context. so that its easy for any child component to dispatch an action to the store (i.e state on the Todos Component).
Hooks — to manage logic of model state
There are two ways, we can manage the logic of state in the functional component using hooks.
- useEffect — Hook helps us to write the logic of handling state, that needs to be happened on the life cycle - stages of a component.
- custom hooks — Helps to consolidate the logic of handling state so that it paves the way for re-usability across the component.
useEffect
sample above — we have a component which shows the current date and time to the user.
To keep the time up-to date, we need the logic to increment the time for every second. That logic goes into useEffect
— hook which helps you to handle the side effects.
useEffect
accepts two arguments,
- Fat Function — function which runs whenever React plans for re-rendering (by default — for every re-rendering plan, it runs - but we can control that)
- Arrary of props — this array helps to controls the effect function execution in # 1 argument. If array is empty — # 1 will execute only during mount and un-mount phase of the component. If array holds props then that prop change will be the evidence for the execution of #1.
custom hooks
in the sample —we segregated the date update logic as separate function which is custom hook. so that it can be used in both DateTime
and Watch
Component.
Rules of Hooks
We have to follow two guidelines on using hooks and React team have provided Linter plugin for same.
1. Hooks should be used at the root level of the functional component. means Hooks should not be conditional (under the hood - react remembers the hooks with its order of execution, so you should not block)
const NameDisplay = () => {
if(iAmTrue) { // This is wrong
const [name, setName] = useState(‘Mohan Ram’);
}
...
}
2. Only call hooks from react function or from custom hooks.
Other Hooks
Most important hooks - whose usability is expected as high are covered above. In addition to those — We have many other hooks, they are
- useContext — helps to consume the Provider Context which is created with
React.createContext
- useCallback — Helps to memoize the callback function which has expensive computation.
- useMemo — similar to useCallback — the difference is useCallback return memoized callback function but useMemo returns memoized value.
I actually thought
useMemo
memoize all inputs passed to it, but it actually memoize only the immediate previous inputs. You can call as ‘memoize last’ as Dan Abramov termed here
4. useRef — returns a mutable ref object whose .current
property is initialized to the passed argument (initialValue
). The returned object will persist for the full lifetime of the component.
5. useImperativeMethods — customizes the instance value that is exposed to parent components when using ref.
6. useLayoutEffect — similar to useEffect — the difference is - it fires synchronously after all DOM mutations. Use this to read the layout from the DOM and synchronously re-render.
Conclusion
Hooks help you to manage the functional component state efficiently.
useState
, useReducer
and useEffect
are the major hooks which are mostly expected to be used on development.
Please find the code base in
here is a Live demo
In simple — Hooks is powerful. try it!!!