What are React Hooks ?

Motivation
Each lifecycle method often contains a mix of unrelated logic. Mutually related code that changes together gets split apart, but completely unrelated code ends up combined in a single method.
We have to understand how this works in JavaScript, which is very different from how it works in most languages. We have to remember to bind the event handlers.
To overcome this problems, React needed a better primitive for sharing stateful logic and this is how Hooks came into picture.

What are Hooks ?
Hooks are functions that let you use React state and lifecycle features from function components.
Rules of Hooks
1. Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function before any early returns.
2. Only Call Hooks from React Functions. Don’t call Hooks from regular JavaScript functions.

useState Hook

const [state, setState] = useState(initialState);


The useState is a Hook that lets you add React state to function components.
Returns a stateful value, and a function to update it.
The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.
setState(newState);


Example:

const [count, setCount] = useState(0);


Note:
Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return { ...prevState, ...updatedValues };
});


useEffect Hook

useEffect( () => {}, [dependency array] );


The useEffect Hook lets you perform side effects in function components.
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.
The function passed to useEffect will run after the render is committed to the screen.
By default, effects run after every completed render, but you can choose to fire them only when dependency array have changed.


1. Effects run after every completed render if dependency array is not provided.
2. Effects run only one time if an empty dependency array is provided.
(Same as componentDidMount lifecycle method)
3. Effects run after every state mutation if dependency array with states is provided.
(Same as componentDidUpdate lifecycle method)

The clean-up function runs before the component is removed from the UI. If a component renders multiple times, the previous effect is cleaned up before executing the next effect.( Same as componentWillUnmount lifecycle method)

useEffect(() => {
  return () => {
    // Clean up function
  };
});


Example:

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });


useContext Hook

const value = useContext(MyContext);


The argument to useContext must be the context object itself.
Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest above the calling component in the tree.
When the nearest above the component updates, this Hook will trigger a rerender with the latest context value passed to that MyContext.provider. Even if an ancestor uses React.memo or shouldComponentUpdate, a rerender will still happen starting at the component itself using useContext.


Example:

const user = useContext(UserContext);


useMemo Hook
useMemo( () => {}, [dependency array] );


Returns a memoized value.
Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
You may rely on useMemo as a performance optimization.


Example:

const calculation = useMemo(() => expensiveCalculation(state), [state]);


useCallback Hook
useCallback( () => {}, [dependency array] );


Returns a memoized callback/function.
Pass an inline callback/function and an array of dependencies. useCallback will return a memoized version of the callback/function that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.
You may rely on useMemo as a performance optimization.


Example:

const addTodo = useCallback(() => {
  setTodos((t) => [...t, "New Todo"]);
}, [todos]);


useRef Hook

const refContainer = useRef(initialValue);


The useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist between renders. It can be used to store a mutable value that does not cause a re-render when updated. It can be used to access a DOM element directly.


Example:

const count = useRef(0);
const inputElement = useRef();



useReducer Hook

const [state, dispatch] = useReducer(reducer, initialArg, init);


An alternative to useState. Accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method.
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.
React guarantees that dispatch function identity is stable and won’t change on re-renders.
You can also create the initial state lazily. To do this, you can pass an init function as the third argument. The initial state will be set to init(initialArg).


Example:

const [todos, dispatch] = useReducer(reducer, initialTodos);

 

Conclusion :

Hooks are functions that let you use React state and lifecycle features from function components without using class component.

The  hooks we covered are  useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback etc.

To know more about hooks visit below mentioned official website for React Docs.

Reference : https://reactjs.org/docs/hooks-intro.html