R
Reactiflux

help-threads-react

poppingpopper – 19-07 Oct 18

PPoppingPopper10/18/2023
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) 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,
}}
>
Solution:
Message Not Public
Sign In & Join Server To View
Jump to solution
PPoppingPopper10/18/2023
UUUnknown User10/18/2023
Message Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
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.
UUUnknown User10/18/2023
2 Messages Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
I'm trying to see if it's possible to get a deployed link but I don't konw yet.
UUUnknown User10/18/2023
5 Messages Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
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,
}}
>
PPoppingPopper10/18/2023
I'm listening to the parent container's dimensions
No description
PPoppingPopper10/18/2023
No description
Solution
UUUnknown User10/18/2023
3 Messages Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
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>
PPoppingPopper10/18/2023
❤️ Thank you @oldcoder
UUUnknown User10/18/2023
3 Messages Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
@oldcoder How can I mark your message as the answer to this thread?
UUUnknown User10/18/2023
2 Messages Not Public
Sign In & Join Server To View
PPoppingPopper10/18/2023
Thanks again!
UUUnknown User10/20/2023
2 Messages Not Public
Sign In & Join Server To View

Looking for more? Join the community!

R
Reactiflux

help-threads-react

Join Server