React Hooks are functions that enable functional components to manage state, side effects, and other React features.
Before the introduction of Hooks in React 16.8, state and lifecycle methods were primarily associated with class components.
Hooks provide a more concise and expressive way to handle state and side effects in functional components.
Here are some key Concept of React Hooks:
useState is used to add state to functional components. It returns an array with two elements: the current state value and a function that lets you update it.
import React, { useState } from 'react'; const Counter = () => { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); };
useEffect allows functional components to perform side effects.
import React, { useState, useEffect } from 'react'; const DataFetcher = () => { const [data, setData] = useState(null); useEffect(() => { // Fetch data from an API fetch('https://jsonplaceholder.typicode.com/todos/1') .then(response => response.json()) .then(json => setData(json)) .catch(error => console.error(error)); }, []); // Empty dependency array means it runs only once (on mount) return ( <div> <p>Data: {data?.title}</p> </div> ); };
It's similar to `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` lifecycle methods in class components.
`createContext` allows us to create context and wrap components inside `Provider` and pass value from a Provider and allow us to Subscribe value inside component using `useContext API` without introducing nesting.
// YourContext.js import { createContext } from 'react'; const YourContext = createContext(); export default YourContext;
From Parent Component Publish value through `Provider` on key `value`.
import React, { useState } from 'react'; import YourContext from './YourContext'; import ChildComponent from './ChildComponent'; const YourParentComponent = () => { const [name, setName] = useState("Alice"); return ( <YourContext.Provider value={name}> <ChildComponent /> </YourContext.Provider> ); }; export default YourParentComponent;
Subscribe Context using the below example by `useContext` API.
useContext allows us to `subscribe` to React context without introducing nesting.
import React, { useContext } from 'react'; import YourContext from './YourContext'; const ChildComponent = () => { const contextValue = useContext(YourContext); return ( <div> <p>Context Value: {contextValue}</p> </div> ); }; export default ChildComponent;
The useReducer hook is usually preferable to `useState()` when we have complex state logic that involves multiple sub-values or when the next state depends on the previous one.
import React, { useReducer } from 'react'; const initialState = { firstName: "Alice" }; const reducer = (state: any, action: any) => { switch (action.type) { case 'updatename': return { firstName: action.payload }; default: return state; } }; const UpdateProfile = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Profile Name: {state.firstName}</p> <input type="text" value={state.firstName} onChange={(e) => dispatch({ type: 'updatename', payload: e.target.value })} /> </div> ); }; export default UpdateProfile;
useCallback and useMemo are used to memoize functions and values, respectively, preventing unnecessary re-renders.
import React, { useState, useCallback, useMemo } from 'react'; const YourComponent = () => { const [count, setCount] = useState(0); const memoizedCallback = useCallback(() => { // Callback logic }, [count]); const memoizedValue = useMemo(() => { // Value computation for(let i=0; i<1000000; i++) {} return count * 2; }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> <p>Memoized Value: {memoizedValue}</p> </div> ); }; export default YourComponent;