poppingpopper – 19-07 Oct 18

Hey! I'm trying to build a somewhat responsive page and I'm using a resize observer to get the width of the parent element to determine the width of my charts. For some reason the width changes in increments instead of immediately after the debounce interval I've set. Can you help me figure out why this is happening and how I might fix it? (Also open to constructive criticism about the way I'm approaching it as well)
Solution:
Message Not Public
Sign In & Join Server To View
P
PoppingPopper183d ago
Here is the resize observer hook:
import { useEffect, useState } from 'react'
import { useDebouncedCallback } from 'use-debounce'

interface Dimensions {
width: number
height: number
}

export function useDebouncedResizeObserver(element: HTMLElement | null, delay: number): Dimensions {
const [dimensions, setDimensions] = useState<Dimensions>({ width: 0, height: 0 })
const delayedSetDimensions = useDebouncedCallback(setDimensions, delay)

useEffect(() => {
if (!element) return

const resizeObserver = new ResizeObserver((entries) => {
const { width, height } = entries[0].contentRect
delayedSetDimensions(() => ({ width, height }))
})

resizeObserver.observe(element)

// Cleanup observer on unmount
return () => {
resizeObserver.unobserve(element)
}
}, [element, delayedSetDimensions])

return dimensions
}
import { useEffect, useState } from 'react'
import { useDebouncedCallback } from 'use-debounce'

interface Dimensions {
width: number
height: number
}

export function useDebouncedResizeObserver(element: HTMLElement | null, delay: number): Dimensions {
const [dimensions, setDimensions] = useState<Dimensions>({ width: 0, height: 0 })
const delayedSetDimensions = useDebouncedCallback(setDimensions, delay)

useEffect(() => {
if (!element) return

const resizeObserver = new ResizeObserver((entries) => {
const { width, height } = entries[0].contentRect
delayedSetDimensions(() => ({ width, height }))
})

resizeObserver.observe(element)

// Cleanup observer on unmount
return () => {
resizeObserver.unobserve(element)
}
}, [element, delayedSetDimensions])

return dimensions
}
Here is the usage of the width returned
const [parentElement, setParentElement] = useState<HTMLElement | null>(null)
const { width: parentWidth } = useDebouncedResizeObserver(parentElement, 100)

const CHART_HEIGHT = 200
const CHART_WIDTH = useMemo(() => {
return Math.max(parentWidth - 60, 0)
}, [parentWidth])

...

return (
<div
ref={(e) => {
if (!e) return
setParentElement(e.parentElement)
}}
>
...
<div
style={{
height: CHART_HEIGHT,
width: CHART_WIDTH,
}}
>
const [parentElement, setParentElement] = useState<HTMLElement | null>(null)
const { width: parentWidth } = useDebouncedResizeObserver(parentElement, 100)

const CHART_HEIGHT = 200
const CHART_WIDTH = useMemo(() => {
return Math.max(parentWidth - 60, 0)
}, [parentWidth])

...

return (
<div
ref={(e) => {
if (!e) return
setParentElement(e.parentElement)
}}
>
...
<div
style={{
height: CHART_HEIGHT,
width: CHART_WIDTH,
}}
>
P
PoppingPopper183d ago
UU
Unknown User183d ago
P
PoppingPopper183d ago
Yea, what do you want me to do exactly? Just print the width change out without the graphs present? I think I'm experiencing a cascading effect where the width changes but the child content is choking it between width changes.
UU
Unknown User183d ago
P
PoppingPopper183d ago
I'm trying to see if it's possible to get a deployed link but I don't konw yet.
UU
Unknown User183d ago
P
PoppingPopper183d ago
The width is definitely being affected by the graphs as I'm only using the responsive width for the graphs. The width is being used like so in my charts
const [parentElement, setParentElement] = useState<HTMLElement | null>(null)
const { width: parentWidth } = useDebouncedResizeObserver(parentElement, 100)

const CHART_HEIGHT = 200
const CHART_WIDTH = useMemo(() => {
return Math.max(parentWidth - 60, 0)
}, [parentWidth])

...

return (
<div
ref={(e) => {
if (!e) return
setParentElement(e.parentElement)
}}
>
...
<div
style={{
height: CHART_HEIGHT,
width: CHART_WIDTH,
}}
>
const [parentElement, setParentElement] = useState<HTMLElement | null>(null)
const { width: parentWidth } = useDebouncedResizeObserver(parentElement, 100)

const CHART_HEIGHT = 200
const CHART_WIDTH = useMemo(() => {
return Math.max(parentWidth - 60, 0)
}, [parentWidth])

...

return (
<div
ref={(e) => {
if (!e) return
setParentElement(e.parentElement)
}}
>
...
<div
style={{
height: CHART_HEIGHT,
width: CHART_WIDTH,
}}
>
P
PoppingPopper183d ago
I'm listening to the parent container's dimensions
No description
P
PoppingPopper183d ago
No description
Solution
UU
Unknown User183d ago
P
PoppingPopper183d ago
Haha! I am so dumb, I was thinking about what you said
i didnt get why this complexity instead giving w-full to parent
Then I realized I used to have a reason for why I needed to listen to width changes. But not anymore. So I removed all that code and just let the width fill the flex container and its working. <:Laughing_Facepalm:1084929862810222622>
P
PoppingPopper183d ago
❤️ Thank you @oldcoder
UU
Unknown User183d ago
P
PoppingPopper183d ago
@oldcoder How can I mark your message as the answer to this thread?
UU
Unknown User183d ago
P
PoppingPopper183d ago
Thanks again!
UU
Unknown User181d ago