I placed a div in A4 format inside a fixed div with a height of 500px and dynamic width in a scrollable manner. The reason for the dynamic width of this div is that there is a sidebar on the screen, and this sidebar can expand and contract. So far, I don't have a problem. However, I am placing a Stage using the Konva library inside the A4 format div. This stage only accepts numeric values for width and height, so I can't provide values like "100%". I want this stage to adjust its width and height in the same way as its parent div. How can I achieve this? I tried referencing and managing it with state, but I couldn't get the exact result I wanted.
I want this stage to adjust its width and height in the same way as its parent div. How can I achieve this? I tried referencing and managing it with state, but I couldn't get the exact result I wanted.
const Home = () => {
const [width, setWidth] = useState(0)
const myComponentRef = useRef(null)
const { sideBarStatus } = useContext(SidebarContext)
const [rectangles, setRectangles] = useState(initialRectangles)
const [selectedId, selectShape] = useState(null)
useEffect(() => {
// Function to update width
const updateWidth = () => {
if (myComponentRef.current) {
setWidth(myComponentRef.current.clientWidth)
}
}
updateWidth()
window.addEventListener('resize', updateWidth)
return () => {
window.removeEventListener('resize', updateWidth)
}
}, [sideBarStatus])
const checkDeselect = e => {
const clickedOnEmpty = e.target === e.target.getStage()
if (clickedOnEmpty) {
selectShape(null)
}
}
return (
<div ref={myComponentRef} style={{ height: 500, display: 'flex', width: '100%', overflow: 'auto' }}>
<div
style={{
border: '2px solid black',
backgroundColor: 'white',
position: 'relative',
overflow: 'auto',
width: '100%',
height: width * Math.SQRT2
}}
>
<Stage width={width} height={width * Math.SQRT2} onMouseDown={checkDeselect} onTouchStart={checkDeselect}>
<Layer>
{rectangles.map((rect, i) => {
return (
<Rectangle
key={i}
shapeProps={rect}
isSelected={rect.id === selectedId}
onSelect={() => {
selectShape(rect.id)
}}
onChange={newAttrs => {
const rects = rectangles.slice()
rects[i] = newAttrs
setRectangles(rects)
}}
/>
)
})}
</Layer>
</Stage>
</div>
</div>
)
}
Home.acl = {
action: 'read',
subject: entitites.home
}
const initialRectangles = [
{
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'red',
id: 'rect1'
},
{
x: 150,
y: 150,
width: 100,
height: 100,
fill: 'green',
id: 'rect2'
}
]
export default Home
useEffect(() => {
const updateDimensions = () => {
if (myComponentRef.current) {
setWidth(myComponentRef.current.clientWidth)
setHeight(myComponentRef.current.clientHeight)
}
}
const resizeObserver = new ResizeObserver(updateDimensions)
if (myComponentRef.current) {
resizeObserver.observe(myComponentRef.current)
}
updateDimensions()
return () => {
if (myComponentRef.current) {
resizeObserver.unobserve(myComponentRef.current)
}
}
}, [sideBarStatus])
I updated my useEffect as well, adding resizeObserver solve my one step late rendering problem , I don't actually know how it works exactly but I hope It works for you too guys.