React Hooks Interview Questions and Answers
Practice React Hooks interview questions and answers organized by difficulty, with revealable explanations and related topics.
Entry questions
1 questions- Question 1Entry
What are React Hooks?
- React React Hooks
Reveal answerHide answer
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class. With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy. This makes it easy to share Hooks among many components or with the community.
Junior questions
5 questions- Question 1Junior
Provide an example of any simple Custom React Hook. Why do we need Custom Hooks?
- React React Hooks
Reveal answerHide answer
A Custom Hook is a stateful function that uses other react built-in hooks (e.g. useState , useCallback etc.) that can wrap around the stateful logic that you wanted to gather in one place and avoid copying and pasting the same logic in multiple components. Consider the increment/decriment custom hook:
const useCounter = () => { const [counter, setCounter] = useState(0); return { counter, // counter value increment: () => setCounter(counter + 1), // function 1 decrement: () => setCounter(counter - 1) // function 2 }; };and then in your component you can use it as follows:
const Component = () => { const { counter, increment, decrement } = useCounter(); return ( <div> <span onClick={decrement}>-</span> <span style={{ padding: "10px" }}>{counter}</span> <span onClick={increment}>+</span> </div> ); } - Question 2Junior
Provide an example of any simple Custom React Hook. Why do we need Custom Hooks?
- React React Hooks
Reveal answerHide answer
A Custom Hook is a stateful function that uses other react built-in hooks (e.g. useState , useCallback etc.) that can wrap around the stateful logic that you wanted to gather in one place and avoid copying and pasting the same logic in multiple components. Consider the increment/decriment custom hook:
const useCounter = () => { const [counter, setCounter] = useState(0); return { counter, // counter value increment: () => setCounter(counter + 1), // function 1 decrement: () => setCounter(counter - 1) // function 2 }; };and then in your component you can use it as follows:
const Component = () => { const { counter, increment, decrement } = useCounter(); return ( <div> <span onClick={decrement}>-</span> <span style={{ padding: "10px" }}>{counter}</span> <span onClick={increment}>+</span> </div> ); } - Question 3Junior
What are advantages of using React Hooks?
- React React Hooks
Reveal answerHide answer
Primarily, hooks in general enable the extraction and reuse of stateful logic that is common across multiple components without the burden of higher order components or render props. Hooks allow to easily manipulate the state of our functional component without needing to convert them into class components. Hooks don’t work inside classes (because they let you use React without classes). By using them, we can totally avoid using lifecycle methods, such as componentDidMount , componentDidUpdate , componentWillUnmount . Instead, we will use built-in hooks like useEffect .
- Question 4Junior
How to access DOM elements in React?
- React Hooks React
Reveal answerHide answer
One of the useful application of the useRef() hook is to access DOM elements. This is performed in 3 steps:
- Define the reference to access the element const elementRef = useRef() ;
- Assign the reference to ref attribute of the element: ;
- After mounting, elementRef.current points to the DOM element. Consider:
import { useRef, useEffect } from 'react'; function AccessingElement() { const elementRef = useRef(); useEffect(() => { const divElement = elementRef.current; console.log(divElement); // logs <div>I'm an element</div> }, []); return ( <div ref={elementRef}> I'm an element </div> ); } - Question 5Junior
How to call loading function with React useEffect only once?
- React React Hooks
Reveal answerHide answer
If you only want to run the function given to useEffect after the initial render, you can give it an
empty array []as the second argument. For example:
function MyComponent(){ useEffect(() => { loadDataOnlyOnce(); }, []); return <div> { /*...*/} </div>; }
Mid questions
20 questions- Question 1Mid
How to use componentWillMount() in React Hooks?
- React Hooks
Reveal answerHide answer
You cannot use any of the existing lifecycle methods ( componentDidMount , componentDidUpdate , componentWillUnmount etc.) in a hook. They can only be used in class components. And with Hooks you can only use in functional components. You can think of useEffect Hook as componentDidMount , componentDidUpdate , and componentWillUnmount combined.
- Code inside componentDidMount run once when the component is mounted. useEffect hook equivalent for this behaviour is
useEffect(() => { // Your code here }, []); 2. Without the second parameter the useEffect hook will be called on every render (like componentDidUpdate )of the component which can be dangerous:
useEffect(() => { // Your code here }); 3. Hook equivalent of componentWillUnmount() code will be as follows useEffect(() => { window.addEventListener('mousemove', () => {});// returned function will be called on component unmount return () => { window.removeEventListener('mousemove', () => {}) } }, []) - Question 2Mid
Does React useState Hook update immediately?
- React Hooks
Reveal answerHide answer
Problem
And how do you perform an action after useState hook has triggered?
Solution
React useState and setState don’t make changes directly to the state object; they create queues to optimize performance, which is why the changes don’t update immediately. The process to update React state is asynchronous for performance reasons.
To perform side effects after state has change, you must use the useEffect
- Question 3Mid
When writing a Custom Hook, what is the difference between it and a normal function?
- React Hooks
Reveal answerHide answer
Hooks use a stateful closure around the invocation of the function component to store the state on behalf of that component instance. That closure is maintained by React. Custom hook will only be "stateful" if you use state with useState inside (or something that implements
useState ),Hooks should be called from the React code only not from the regular JS functions. Hence, Hooks' scope is limited to the React code world and has more power to do a lot with React code, In the class-based components, the Hooks won't work but regular functions will. In the regular JS functions, you can't access useState , useEffect , useContext etc. but in react custom hooks I can.
- Question 4Mid
Can you initialise state from a function? Provide and example
- React Hooks
Reveal answerHide answer
Yes! Consider:
const StateFromFn = () => { const [token] = useState(() => { let token = window.localStorage.getItem("my-token");return token || "default#-token#"
}) return <div>Token is {token}</div> } - Question 5Mid
Do two components using the same Hook share state?
- React Hooks
Reveal answerHide answer
No. Custom Hooks are a mechanism to reuse stateful logic (such as setting up a subscription and remembering the current value), but every time you use a custom Hook, all state and effects inside of it are fully isolated.
- Question 6Mid
When writing a Custom Hook, what is the difference between it and a normal function?
- React Hooks
Reveal answerHide answer
Hooks use a stateful closure around the invocation of the function component to store the state on behalf of that component instance. That closure is maintained by React. Custom hook will only be "stateful" if you use state with useState inside (or something that implements
useState ),Hooks should be called from the React code only not from the regular JS functions. Hence, Hooks' scope is limited to the React code world and has more power to do a lot with React code, In the class-based components, the Hooks won't work but regular functions will. In the regular JS functions, you can't access useState , useEffect , useContext etc. but in react custom hooks I can.
- Question 7Mid
What are the advantages of Batching in ReactJS?
- React React Hooks
Reveal answerHide answer
Batching is great for performance because it avoids unnecessary re-renders. Batching also prevents your component from rendering half-finished states where only one state variable was updated, which may cause bugs. Another reason to use batching is when the web application grows, the number of nested components will increase. Therefore, if a parent component executes an unbatched state updated, the entire component tree will be re-rendered per state update that is expensive.
- Question 8Mid
Which lifecycle methods of class component is replaced by useEffect in functional component?
- React React Hooks
Reveal answerHide answer
The lifecyce methods replaced by useEffect Hooks of functional component are
componentDidMount() , componentDidUpdate() , and componentWillUnmount()componentDidMount : is equivalent for running an effect once. For example:
useEffect(() => { console.log("This is useEffect Hook equivalent of componentDidMount lifecycle method") },[]); Note:* empty array = useEffect hook runs once on mountcomponentDidUpdate : is equivalent for running effects when things change For example:
useEffect(() => { console.log("The name props has changed!"); }, [props.name]); componentWillUnmount : To run ahook as the component is about to unmount, we just have to return a function from the useEffect Hook For example:
useEffect(() => { console.log('running effect'); return () => { console.log('unmount'); } }) - Question 9Mid
Compare React Context Api with useContext React hook
- React Hooks
Reveal answerHide answer
When using the React Context API : We need to wrap our content in a Consumer component and then pass a function as a child just so we could
access (or consume) our state.This introduces unnecessary component nesting and increases the complexity of our code. Consider:
import React from "react"; import ReactDOM from "react-dom";// Create a Context const NumberContext = React.createContext(); // It returns an object with 2 values: // { Provider, Consumer } function App() { // Use the Provider to make a value available to all // children and grandchildren return ( <NumberContext.Provider value={42}> <div> <Display /> </div> </NumberContext.Provider> ); } function Display() { // Use the Consumer to grab the value from context // Notice this component didn't get any props! return ( <NumberContext.Consumer> {value => <div>The answer is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));When using useContext Hook: lets you “use” context without a Consumer : Consider:
const newContext = React.createContext({ color: 'black' }); const value = useContext(newContext); console.log(value); // this will return { color: 'black' } - Question 10Mid
When would you use useContext hook?
- React Hooks
Reveal answerHide answer
React’s useContext hook makes it easy to pass data throughout your app without manually passing props down the tree. React Context is a way to manage state globally. Consider:
import { useState, createContext } from "react"; import ReactDOM from "react-dom/client"; const UserContext = createContext()Wrap child components in the Context Provider and supply the state value.
function Component1() { const [user, setUser] = useState("Jesse Hall"); return ( <UserContext.Provider value={user}> <h1>{`Hello ${user}!`}</h1> <Component2 user={user} /> </UserContext.Provider> ); }Then you can access the user Context in all components:
import { useState, createContext, useContext } from "react"; function Component5() { const user = useContext(UserContext); return ( <> <h1>Component 5</h1> <h2>{`Hello ${user} again!`}</h2> </> ); } - Question 11Mid
Is there any problem when using useContext Hook?
- React Hooks
Reveal answerHide answer
The problem is that any component consuming state with useContext will re-render when any piece of the Context’s state updates. This resulted in components that were totally divorced from one another causing each other to re-render. In cases where these re-renders were expensive, the memory in users’ browsers accumulated JS Heap footprints in the orders of gigabytes.
- Question 12Mid
Compare useState and useReducer implementations
- React React Hooks
Reveal answerHide answer
useState updates state with setState , while useReducer with dispatch function. useState passes down all the setState custom helper functions, while useReducer passes down just the dispatch function. useState needs to wrap functions in useCallback (if we want to memorize them), while dispatch function is already memorized. useState easier to write, useReducer is harder to implement and needs more logic to be coded.
- Question 13Mid
Do React Hooks cover all use cases for class components?
- React Hooks React
Reveal answerHide answer
No, The following methods have not been introduced in Hooks yet:
getSnapshotBeforeUpdate getDerivedStateFromError componentDidCatch
- Question 14Mid
How can I make use of Error Boundaries in functional React components?
- React React Hooks
Reveal answerHide answer
As of v16.2.0, there's no way to turn a functional component into an error boundary. The componentDidCatch() method works like a JavaScript catch {} block, but for components. Only class components can be error boundaries. In practice, most of the time you’ll want to declare an error boundary component once and use it throughout your application. Also bear in mind that try/catch blocks won't work on all cases. If a component deep in the hierarchy tries to update and fails, the try/catch block in one of the parents won't work -- because it isn't necessarily updating together with the child. A few third party packages on npm implement error boundary hooks.
- Question 15Mid
What are differences between React.memo() and useMemo() ?
- React Hooks
Reveal answerHide answer
React.memo() is a higher-order component (HOC) that we can use to wrap components that we do not want to re-render unless props within them change useMemo() is a React Hook that we can use to wrap functions within a component. We can use this toensure that the values within that function are re-computed only when one of its dependencies change
- Question 16Mid
What are common use cases for the useMemo ?
- React Hooks
Reveal answerHide answer
The primary purpose of useMemo hook is "performance optimization". It returns a memoized value, It accepts two arguments - create function_ (which should return a value to be memoized) and _dependency array. It will recompute the memoized value only when one of the dependencies has changed. Using useMemo you achieve: referential equality of the values (to further send them to props of the components to potentially avoid re-
renders)eliminate redoing of the computationally expensive operations for same parameters For example:
function App() { const [data, setData] = useState([....]); function format() { console.log('formatting....'); // this will print only when data has changed const formattedData = []; data.forEach(item => { const newItem = //...do soemthing here, if (newItem) { formattedData.push(newItem); } }) return formattedData; } const formattedData = useMemo(format, [data]) return ( <> {formattedData.map(item => ( <div key={item.id}> {item.title} </div> ))} </> ) } - Question 17Mid
What are production use cases for the useRef ?
- React Hooks
Reveal answerHide answer
useRef simply returns a plain Javascript object. Its value can be accessed and
modified (mutability) as manytimes as you need without worrying about rerender. useRef value will persist (won't be reset to the initialValue unlike an ordinary object defined in your function component; it persists because useRef gives you the same object instead of creating a new one on subsequent renders) for the component lifetime and across re-renders. useRef hook is often used to store values instead of DOM references. These values can either be a state that does not need to change too often or a state that should change as frequently as possible but should not trigger full re-rendering of the component. For example:
const refObject = useRef(initialValue); - Question 18Mid
Explain the difference between useState and useRef hooks?
- React Hooks
Reveal answerHide answer
- Updating a reference created by useRef doesn't trigger re-rendering, while updating the state ( setState )
makes the component re-render; 2. useRef returns anobject with a current property holding the actual value. In contrast, useState returns an array with two elements. 3. useRef‘s current property is mutable, but useState‘s state variable is not. 4. The reference update is synchronous (the updated reference value is available right away), while the state update is
asynchronous (the state variable is updated after re-rendering). Using useRef - no re-renders const countRef = useRef(0); const handle = () => { countRef.current++; console.log(`Clicked ${countRef.current} times`); }; Using useState - triggers re-render const [count, setCount] = useState(0); const handle = () => { const updatedCount = count + 1; console.log(`Clicked ${updatedCount} times`); setCount(updatedCount); }; - Question 19Mid
What does Batching mean in ReactJS?
- React React Hooks
Reveal answerHide answer
Batching is nothing but grouping React multiple state updates together into a single render state to achieve better computational performance. Until React 18, we only batched updates during the React event handlers. Updates inside of promises , setTimeout , native event handlers, or any other event were not batched in React by default.
function App() { const [count, setCount] = useState(0); const [flag, setFlag] = useState(false); function handleClick() { setCount(c => c+1); // Does not re-render yet setFlag(f => !f); // Does not re-render yet // React will only re-render once at the end (that's batching!) } return ( <div> <button onClick={handleClick}>Next</button> <h1 style={{color: flag ? "blue": "black"}}>{count}</h1> </div> ) } - Question 20Mid
When would you use useRef ?
- React Hooks React
Reveal answerHide answer
The main use cases:
- To store a ref to DOM elements so you can later do something with them: Consider:
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text"/> <button onClick={onButtonClick}>Focus the input</button> </> ); } 2. To store values without triggering re-renders:Consider:
function Counter(){ const [count, setCount] = useState(0); const prevCountRef = useRef(); useEffect(() => { prevCountRef.current = count; }); const prevCount = prevCountRef.current; return <h1>Now: {count}, before: {prevCount} </h1>; }
Expert questions
6 questions- Question 1Expert
Can we mimic componentWillMount() using React Hooks?
- React Hooks
Reveal answerHide answer
This is the way how I simulate constructor in functional components using the useRef hook.
export const useComponentWillMount = (func) => { const willMount = useRef(true) if (willMount.current) func() willMount.current = false }// or export const useComponentWillMount = (func) => { useMemo(func, []) }And usage:
const Component = (props) => { useComponentWillMount(() => console.log("Runs only once before component mounts")); ... return ( <div>{...}</div> ); } - Question 3Expert
How can I force component to re-render with Hooks in React?
- React Hooks
Reveal answerHide answer
This is possible with useState or useReducer , since useState uses useReducer internally:
const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []);useCallback memoizes forceUpdate , so it stays constant during component lifespan and can be passed as a prop safely. updateState({}) updates the state with new object on each forceUpdate call, this results in a re- render. So yes, it forces an update when being called. Note: forceUpdate isn't intended to be used under normal circumstances, only in testing or other outstanding cases. This situation may be addressed in a more conventional way.
- Question 4Expert
Can a custom React hook return JSX?
- React React Hooks
Reveal answerHide answer
While there is no hardcore restriction on how you should define custom hooks and what logic should contain, it's an anti-pattern to write hooks that return JSX. There are a few downsides to using hooks to return JSX When you write a hook that returns JSX component, you are essentially defining the component within the functional component, so on each and every re-render you will be creating a new instance of the component. This will lead to the component being unmounted and mounted again. This is bad for performance and also buggy if you have stateful login within the component as the state will get reset with every re-render of the parent By defining a JSX component within the hook, you are taking away the option of lazy loading your component if the need be. Any performance optimization to the component will require you to make use of useMemo which doesn't give you the flexibility of a custom comparator function like React.memo()
The benefit on the other hand is that you have control over the state of the component in the parent. However, you can still implement the same logic by using a controlled component approach
- Question 5Expert
When would you want to avoid useEffect and use useLayoutEffect instead?
- React Hooks
Reveal answerHide answer
If your effect is mutating the DOM (via a DOM node ref) and the DOM mutation will change the appearance of the DOM node between the time that it is rendered and your effect mutates it, then you don't want to use useEffect . You'll want to use useLayoutEffect . Otherwise, the user could see a flicker when your DOM mutations take effect. This is pretty much the only time you want to avoid useEffect and use useLayoutEffect instead.
- Question 7Expert
Can a custom React hook return JSX?
- React React Hooks
Reveal answerHide answer
While there is no hardcore restriction on how you should define custom hooks and what logic should contain, it's an anti-pattern to write hooks that return JSX. There are a few downsides to using hooks to return JSX When you write a hook that returns JSX component, you are essentially defining the component within the functional component, so on each and every re-render you will be creating a new instance of the component. This will lead to the component being unmounted and mounted again. This is bad for performance and also buggy if you have stateful login within the component as the state will get reset with every re-render of the parent By defining a JSX component within the hook, you are taking away the option of lazy loading your component if the need be. Any performance optimization to the component will require you to make use of useMemo which doesn't give you the flexibility of a custom comparator function like React.memo() The benefit on the other hand is that you have control over the state of the component in the parent. However, you can still implement the same logic by using a controlled component approach
- Question 8Expert
Explain the difference between useMemo vs useEffect + useState usage in that code
- React Hooks
Reveal answerHide answer
Problem
Consider: useEffect + useState
import { expensiveCalculation } from "foo"; function useCalculate(someNumber: number): number { const [result, setResult] = useState<number>(null); useEffect(() => { setResult(expensiveCalculation(someNumber)); }, [someNumber]); return result; } useMemo import { expensiveCalculation } from "foo"; function useCalculateWithMemo(someNumber: number): number { return useMemo(() => { return expensiveCalculation(someNumber); }, [someNumber]); }; Are there any benefits in using useMemo (e.g. for an intensive function call) instead of using a combination ofuseEffect and useState ?
Solution
The useEffect and setState will cause extra renders on every change: the first render will "lag behind" with stale data and then it'll immediately queue up an additional render with the new data. Lets suppose x is initially 0: The useMemo version immediately renders 1 . The useEffect version renders null , then after the component renders the effect runs, changes the state, and queues up a new render with 1 . Then if we change x to 2: The useMemo runs and 3 is rendered. The useEffect version runs, and renders 1 again, then the effect triggers and the component reruns with the correct value of 3 . In terms of how often expensiveCalculation runs, the two have identical behavior, but the useEffect version is causing twice as much rendering which is bad for performance. Plus, the useMemo version is just cleaner and more readable,
Senior questions
14 questions- Question 4Senior
Explain why and when would you use useMemo() ?
- React React Hooks
Reveal answerHide answer
Why: In the lifecycle of a component, React re-renders the component when an update is made. When React checks for any changes in a component, it may detect an unintended or unexpected change due to how JavaScript handles equality and shallow comparisons. This change in the React application will cause it to re-render unnecessarily. Additionally, if that re-rendering is an expensive operation, like a long for loop , it can hurt performance. Expensive operations can be costly in either time, memory, or processing. When: Optimal if the wrapped function is large and expensive.
**How: **Memoization is an optimization technique which passes a complex function to be memoized. In memoization, the result is “remembered” when the same parameters are passed-in subsequently.
const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);useMemo takes in a function and an array of dependencies. The dependency’s list are the elements useMemo watches: if there are no changes, the function result will stay the same. Otherwise, it will re-run the function. If they don’t change, it doesn’t matter if our entire component re-renders, the function won’t re-run but instead return the stored result.
- Question 5Senior
When to use useCallback , useMemo and useEffect ?
- React React Hooks
Reveal answerHide answer
useEffect - It's the alternative for the class component lifecycle methods componentDidMount , componentWillUnmount , componentDidUpdate , etc. You can also use it to create a side effect when dependencies change, i.e. "If some variable changes, do this". useCallback - On every render, everything that's inside a functional component will run again. If a child component has a dependency on a function from the parent component, the child will re-render every time the parent re-renders even if that function "doesn't change" (the reference changes, but what the function does won't). It's used for optimization by avoiding unnecessary renders from the child, making the function change the reference only when dependencies change. You should use it when a function is a dependency of a side effect e.g. useEffect . useMemo - It will run on every render, but with cached values. It will only use new values when certain dependencies change. It's used for optimization when you have expensive computations.
- Question 6Senior
Is there a React hook equivalent to componentDidCatch ?
- React Hooks
Reveal answerHide answer
Problem
And how can I add Error Boundary to the functional component?
Solution
There is not a React hook equivalent of componentDidCatch . However, the React team plans to add one soon. For functional components you can sometimes use try...catch to catch component errors. Also bear in mind that try/catch blocks won't work on all cases. If a component deep in the hierarchy tries to updates and fails, the try/catch block in one of the parents won't work -- because it isn't necessarily updating together with the child.
function myComponent(...) { // Initialize state variables. // Initialize context variables. // Initialize custom hooks. // ... try { // Define internal functions. // Define internal variables. return ( <SomeThing /> ) } catch (error) { // Catch internal functions, variables and return (jsx) errors. // You can also create a lib to log the error to an error reporting service // and use it here. } }The try...catch block is the Error Boundry here.
Note: that approach has some limitations: when you use a hook like useEffect and you use some internal functions in it, you cannot put that internal function into try...catch(Error Boundary) block because you should define that function on top of useEffect hook (why?) and you shouldn't use useEffect conditionally (why?)!
- Question 7Senior
How would you store non-state/ instance variables in functional React components?
- React Hooks React
Reveal answerHide answer
You can use useRef hook (it's the recommended way stated in docs). useRef returns an object whose reference would not change across re-renders, the actual value for foo is then kept in the current property of that object. Declaring variable: const a = useRef(5) // 5 is initial value getting the value: a.current setting the value: a.current = my_value
- Question 8Senior
Do Hooks replace render props and higher-order components (HOC)?
- React Hooks
Reveal answerHide answer
Often, render props and higher-order components render only a single child. React team thinks Hooks are a simpler way to serve this use case.
There is still a place for both patterns (for example, a virtual scroller component might have a renderItem prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree.
- Question 9Senior
Explain the use of useLayoutEffect React Hook
- React Hooks
Reveal answerHide answer
useLayoutEffect React Hook runs synchronously immediately after React has performed all DOM mutations. This can be useful if you need to make DOM measurements (like getting the scroll position or other styles for an element) and then make DOM mutations or trigger a synchronous re-render by updating the state. As far as scheduling and lifecycle, this works the same way as componentDidMount and componentDidUpdate . Your code runs immediately after the DOM has been updated, but before the browser has had a chance to "paint" those changes (the user doesn't actually see the updates until after the browser has repainted).
- Question 10Senior
Are there any problems using useCallback ?
- React Hooks
Reveal answerHide answer
Look at the common anti-pattern of using useCallback :
import { useCallback } from 'react'; function MyComponent() { // Contrived use of `useCallback()` const handleClick = useCallback(() => { // handle the click event }, []); return <MyChild onClick={handleClick}/>; } function MyChild({ onClick }) { return <button onClick={onClick}>I am a child</button>; } SinceMyChild component is light and its re-rendering doesn't create performance issues, using useCallback here is not important. Using useCallback you also increased code complexity.
- Question 11Senior
Provide a good example of using useCallback hook in React
- React Hooks
Reveal answerHide answer
Imagine you have a component that renders a big list of items. To prevent useless list re-renderings, you wrap it into React.memo() .
import useSearch from './fetch-items'; function MyBigList({ term, onItemClick }) { const items = useSearch(term); const map = item => <div onClick={onItemClick}>{item}</div>; return <div>{items.map(map)}</div>; } export default React.memo(MyBigList);The parent component of MyBigList provides a handler function to know when an item is clicked:
import { useCallback } from 'react'; export function MyParent({ term }) { const onItemClick = useCallback(event => { console.log('You clicked ', event.currentTarget); }, [term]); return ( <MyBigList term={term} onItemClick={onItemClick} /> ); } onItemClick callback is memoized by useCallback() . As long as term is the same, useCallback() returns thesame function object that passed to NyBigList as a prop. When MyParent component re-renders, onItemClick function objectremains the same and doesn't break the memoization of MyBigList . That's the right use case to use useCallback .
- Question 13Senior
When to use useState vs useReducer ?
- React React Hooks
Reveal answerHide answer
The decision of whether to use useState or useReducer isn't always black and white; there are many shades of grey. But,
use useState if you have: JavaScript primitives as state Simple state transitions Business logic within your component Different properties that don't change in any correlated way and can be managed by multiple useState hooks use useReducer if you have: JavaScript objects or arrays as state Complex state transitions Complicated business logic more suitable for a reducer function (to separate concern of it) Different properties tied together that should be managed in one state object (when state depends on state)
- Question 14Senior
When shall we use useReducer hook in ReactJS?
- React React Hooks
Reveal answerHide answer
useReducer is an alternative to useState . 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. An example will be a list of items, where you need to add, update and remove items in the state, Here you might have noticed that the state management logic takes a good part of the component body. useReducer helps to separate the concerns of rendering vs a concern of state management. 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> </> ); }React guarantees that dispatch function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list. https://dmitripavlutin.com/5c33affee33e7c40e73028fb48a8367b/diagram.svg
- Question 15Senior
When would you use flushSync in ReactJS?
- React React Hooks
Reveal answerHide answer
React 18 adds out-of-the-box performance improvements by doing more batching (automated) by default. Batching is when React groups multiple state updates into a single re-render for better performance. To opt-out of automatic batching, you can use flushSync so your component will be re-rendered after each state update. You might need it when for example some code may depend on reading something from the DOM immediately after a state change. Consider with automated batching:
function handleClick() { setCount(c => c + 1); setFlag(f => !f); // React will only re-render once at the end (that's batching!) }Consider with flushSync :
import { flushSync } from 'react-dom'; function handleClick() { flushSync(() => { setCounter(c => c + 1); }); // React has updated the DOM by now flushSync(() => { setFlag(f => !f); }); // React has updated the DOM by now } - Question 17Senior
When to use useCallback , useMemo and useEffect ?
- React React Hooks
Reveal answerHide answer
useEffect - It's the alternative for the class component lifecycle methods componentDidMount , componentWillUnmount , componentDidUpdate , etc. You can also use it to create a side effect when dependencies change, i.e. "If some variable changes, do this". useCallback - On every render, everything that's inside a functional component will run again. If a child component has a dependency on a function from the parent component, the child will re-render every time the parent re-renders even if that function "doesn't change" (the reference changes, but what the function does won't). It's used for optimization by avoiding unnecessary renders from the child, making the function change the reference only when dependencies change. You should use it when a function is a dependency of a side effect e.g. useEffect .
useMemo - It will run on every render, but with cached values. It will only use new values when certain dependencies change. It's used for optimization when you have expensive computations.
- Question 19Senior
Explain why and when would you use useMemo() ?
- React React Hooks
Reveal answerHide answer
Why: In the lifecycle of a component, React re-renders the component when an update is made. When React checks for any changes in a component, it may detect an unintended or unexpected change due to how JavaScript handles equality and shallow comparisons. This change in the React application will cause it to re-render unnecessarily. Additionally, if that re-rendering is an expensive operation, like a long for loop , it can hurt performance. Expensive operations can be costly in either time, memory, or processing.
When: Optimal if the wrapped function is large and expensive.
**How: **Memoization is an optimization technique which passes a complex function to be memoized. In memoization, the result is “remembered” when the same parameters are passed-in subsequently.
const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);useMemo takes in a function and an array of dependencies. The dependency’s list are the elements useMemo watches: if there are no changes, the function result will stay the same. Otherwise, it will re-run the function. If they don’t change, it doesn’t matter if our entire component re-renders, the function won’t re-run but instead return the stored result.
- Question 20Senior
What's the difference between useCallback and useMemo in practice?
- React React Hooks
Reveal answerHide answer
With useCallback you memoize functions, useMemo memoizes any computed value:
const fn = () => 42 // assuming expensive calculation here const memoFn = useCallback(fn, [dep]) // (1) const memoFnReturn = useMemo(fn, [dep]) // (2) (1) will return a memoized version of fn - same reference across multiple renders, as long as dep is the same. But every time you invoke memoFn , that complex computation starts again. (2) will invoke fn every time dep changes and remember its returned value ( 42 here), which is then stored in memoFnReturn .