React Hooks at a Glance

All important facts about React Hooks……getting started with them!!

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

Hooks are functions that let you “hook into” React state and lifecycle features from function components.

  • It’s hard to reuse stateful logic between components.
  • Complex components become hard to understand.
  • Classes confuse both people and machines.(know this pt. in detail…….click here)
  1. Always call Hooks at the top level.
  2. Only call Hooks from React functions

📌 State Hook

Hook state is the new way of declaring a state in React app. Hook uses useState() functional component for setting and retrieving state.

import React, { useState } from 'react';
function Example() {
// .........
}

What do we pass to useState as an argument? The only argument to the useState() Hook is the initial state.

import React, { useState } from 'react';

function Example() {
// Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0);

The example below renders a counter with a value of 0. When you click the button, it increments the value by 1. The initial value of the component is defined using useState.

 1:  import React, { useState } from 'react'; 2:
3: function Example() {
4: const [count, setCount] = useState(0); 5:
6: return (
7: <div>
8: <p>You clicked {count} times</p>
9: <button onClick={() => setCount(count + 1)}>10:
Click me
11: </button>
12: </div>
13: );
14: }
Pen React Hook example with Counter by Adeneye Abiodun David.

Before the release of React Hooks, this example would have used more lines of code, as we’d have had to make use of a class component.

⚡️ Effect Hook

useEffect drastically simplifies side effects in components by making it much easier to run side effects when props/state change. useEffect also makes organizing side effects easier since they are each given their own useEffect hook instead of being crammed into a few life cycle methods.

useEffect takes an optional second parameter which is an array of values. This array of values is compared during each re-render with the previous render’s array values and the side effect will only be run if the values in the array changed since the last render. This means if you only want to run a side effect on mount then you can pass an empty array as the second parameter since that will never change between renders.

useEffect(() => {
console.log('Only run on mount')
}, [])

Having this second array parameter is really nice since it allows side effects to be run whenever any value changes.

useEffect(() => {
console.log('Only run on url change')
}, [url])

Let us understand Hook Effect with the following example in which we set the initial state of variable color using useState that is Sea, as we change the value of color it renders useEffect hook which sets the background color.

import React, { useState, useEffect } from 'react';
const colors = {
Sea: '#a2ccb6',
Sand: '#fceeb5',
Peach: '#ee786e',
}
const App = () => {
const [color, setColor] = useState(colors.Sea)
useEffect(
() => {
document.body.style.background = color
},
[color]
)
return (
<Fragment>
<select value={color} onChange={e => setColor(e.target.value)}>
{Object.entries(colors).map(([name, value]) => (
<option key={`color--${name}`} value={value}>
{name}
</option>
))}
</select>
<h1>{color}</h1>
</Fragment>
)
}

📌 useContext

In a typical React application, data is passed top-down (parent to child) via props, but such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.

useContext is a substantial step forward. It accepts the value created by the existing React.createContext function (the same one you would pull .Consumer off to use as a render prop) and returns the current value from that context provider. The component will rerender whenever the context value change, just like it would for state or props.

In order to use context in a function component you no longer need to wrap your JSX in a consumer. Instead all you need to do is pass your context to the useContext hook and it will do all the magic for you. Here is an example.

function GrandChildComponent() {
const { theme, setTheme } = useContext(ThemeContext)
return (
<>
<div>The theme is {theme}</div>
<button onClick={() => setTheme('light')}>
Change To Light Theme
</button>
</>
)
}

This simplifies code related to context and makes working with context so much easy.

below is an example to change theme using useContext, you may check out the code and know how things are working….

Note: The 3 hooksuseState, useEffect, and useContext are the basic hooks. It’s possible to write entire applications using only them.

Additional Hooks(advance hooks)

⚡useReducer

An alternative to useState. Accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method. (If you’re familiar with Redux, you already know how this works.)

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.

const initialState = {count: 0};

function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}

function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}

useRef

const refContainer = useRef(initialValue);

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.

A common use case is to access a child imperatively:

function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}

Conclusion

Hooks solve a wide variety of seemingly unconnected problems in React that we encounter while writing and maintaining tons of thousands of components. With Hooks, we can extract stateful logic from a component so it can be tested independently and reused. Hooks allow us to reuse stateful logic without changing your component hierarchy.

sources…..react-docs.

to learn more checkout yt videos…..link1

Don’t forget to give us your 👏 !

Tech enthusiast | Developer | Learner

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store