name hooks with “use”, place in root of src/
useConsoleLog.js
import { useEffect } from "react";
function useConsoleLog(varName) {
useEffect(() => {
console.log(varName);
}, [varName]);
}
export default useConsoleLog;
This hook will console log a variable's value whenever it gets updated. Since we call console.log() we will need to use the useEffect hook
App.js
import { useState } from "react";
// import useConsoleLog hook
import useConsoleLog from "./useConsoleLog";
function App() {
const [count, setCount] = useState(0);
useConsoleLog(count);
function increment() {
setCount(prevCount => prevCount + 1)
}
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>Plus 1</button>
</div>
);
}
export default App;
This is a simple app with an h1 heading that shows the value of the count state variable and a button with an onClick event-handling attribute which, when triggered, invokes the increment() function

usePrevious is to remember the previous value of a variable (day) across renders, without causing extra re-rendersimport React, { useState, useEffect, useRef } from "react";
export default function App() {
const [day, setDay] = useState("Monday");
const prevDay = usePrevious(day);
const getNextDay = () => {
if (day === "Monday") {
setDay("Tuesday")
} else if (day === "Tuesday") {
setDay("Wednesday")
} else if (day === "Wednesday") {
setDay("Thursday")
} else if (day === "Thursday") {
setDay("Friday")
} else if (day === "Friday") {
setDay("Monday")
}
}
return (
<div style={{padding: "40px"}}>
<h1>
Today is: {day}<br />
{
prevDay && (
<span>Previous work day was: {prevDay}</span>
)
}
</h1>
<button onClick={getNextDay}>
Get next day
</button>
</div>
);
}
function usePrevious(val) {
const ref = useRef();
useEffect(() => {
ref.current = val;
}, [val]);
return ref.current;
}
| Concept | Explanation |
|---|---|
| Why previous value works | Ref is updated after render |
| Why effect is needed | Prevents overwriting previous value |
| Why no re-render | Updating a ref does not trigger render |
Role of getNextDay |
Triggers state change and re-render |
function usePrevious(val)
useRef gives you a container (ref.current) that persists across rendersref.current does not trigger a re-renderuseEffect runs after render - innate behaviorRender #1 — Initial render
| Phase | What happens |
|---|---|
| State before render | day = "Monday" |
| Hook call | usePrevious(day) with val = "Monday" |
useRef() |
Creates ref with ref.current = undefined |
useEffect |
Scheduled to run after render |
| Return from hook | prevDay = undefined |
| App values | day = "Monday", prevDay = undefined |
| UI output | Shows “Today is: Monday” |
| UI output | Previous day line not shown |
| After commit | ref.current = "Monday" |
| Re-render? | No (ref update only) |
User action — Click “Get next day”
| Step | Behavior |
|---|---|
| Function called | getNextDay() |
| Condition | day === "Monday" |
| State update | setDay("Tuesday") |
| Result | Schedules re-render |
Render #2 — After click
| Phase | What happens |
|---|---|
| State before render | day = "Tuesday" |
| Hook call | usePrevious(day) with val = "Tuesday" |
useRef() |
Returns same ref object |
ref.current |
"Monday" |
useEffect |
Scheduled to run after render |
| Return from hook | prevDay = "Monday" |
| App values | day = "Tuesday", prevDay = "Monday" |
| UI output | Shows “Today is: Tuesday” |
| UI output | Shows “Previous work day was: Monday” |
| After commit | ref.current = "Tuesday" |
| Re-render? | No (ref update only) |