Enthusiast trying to learn nextjs.
I want to be able to have a component that shows window width and height with a tailwindcss breakpoint shown on the button when clicked, as a stepping stone to a continuous display. I decided that clicking a button to show the current window width and height would be easier than setting up an event listener to continuously change the displayed values. I also wanted to show the current "breakpoint" value according to the standard TailwindCSS breakpoints.
The versions of the packages used are shown here.
"dependencies": {
"axios": "^1.1.2",
"daisyui": "^2.31.0",
"gray-matter": "^4.0.3",
"marked": "^4.1.1",
"next": "12.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.4.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.7",
"autoprefixer": "^10.4.12",
"eslint": "^8.25.0",
"eslint-config-next": "12.3.1",
"postcss": "^8.4.17",
"tailwindcss": "^3.1.8"
}
and the component WidthHeightButton.js is here:
export default function WidthHeightButton() {
const [widthParam, setWidth] = useState(55)
const [heightParam, setHeight] = useState(55)
const [tailwindBreakpoint, setTailwindBreakpoint] = useState("empty")
console.log("[WidthHeightButton] check array used to destructure setWidth is a function:", typeof setWidth)
function handleClick() {
console.log("[WidthHeightButton] width x height:", window.innerWidth, "x", window.innerHeight)
setWidth(window.innerWidth)
setHeight(window.innerHeight)
console.log("typeof widthParam:", typeof widthParam, widthParam)
let breakpoint = ""
if (widthParam >= 1536) {
breakpoint = "2xl"
} else if (widthParam >= 1280) {
breakpoint = "xl"
} else if (widthParam >= 1024) {
breakpoint ="lg"
} else if (widthParam >= 768) {
breakpoint = "md"
} else if (widthParam >= 640) {
breakpoint = "sm"
} else {
breakpoint = "default"
}
setTailwindBreakpoint(breakpoint)
}
return (
<button onClick={handleClick} className="my-6 btn btn-secondary">
width x height: {widthParam} x {heightParam} {tailwindBreakpoint}
</button>
)
}
I then invoke the component with It shows WIDTH x HEIGHT: 55 X 55 EMPTY (my default values)
I click the button.
It shows WIDTH x HEIGHT: 677 X 918 DEFAULT (width and height are correct, but not the breakpoint.)
I click the button again.
It shows WIDTH x HEIGHT: 677 X 918 SM (Correct)
Why does it take two clicks?
In response to all the great pointers to this gap in my understanding, I wanted to see if changing the order of operations might get a better result:
import { useState } from "react"
export default function WidthHeightButton() {
const [widthParam, setWidth] = useState(55)
const [heightParam, setHeight] = useState(55)
const [tailwindBreakpoint, setTailwindBreakpoint] = useState("empty")
console.log("[AnotherButton] check array used to destructure setWidth is a function:", typeof setWidth)
function handleClick() {
console.log("[AnotherButton] width x height:", window.innerWidth, "x", window.innerHeight)
let breakpoint = ""
if (window.innerWidth >= 1536) {
breakpoint = "2xl"
} else if (window.innerWidth >= 1280) {
breakpoint = "xl"
} else if (window.innerWidth >= 1024) {
breakpoint ="lg"
} else if (window.innerWidth >= 768) {
breakpoint = "md"
} else if (window.innerWidth >= 640) {
breakpoint = "sm"
} else {
breakpoint = "default"
}
setWidth(window.innerWidth)
setHeight(window.innerHeight)
setTailwindBreakpoint(breakpoint)
console.log("typeof widthParam:", typeof widthParam, widthParam)
}
return (
<button onClick={handleClick} className="my-6 btn btn-secondary">
width x height: {widthParam} x {heightParam} {tailwindBreakpoint}
</button>
)
}
Inspired by your answers, I wanted to see if I could stop the use of one state variable (widthParam) being used to determine another state variable (tailwindBreakpoint). This is one solution to the problem I raised, and results in the correct display with one button click. I have to focus on the great responses given here. I'm not sure if this response is a legitimate answer to my question, but maybe it is a bite sized step in the right direction.