Reputation: 804
I need to dynamically define the size of HTML element and set its height to component. I tried to do this with useRef but it doesn't work as expected because of state which contains the previous value (not the current one). Could someone help me with this?
And here's the link: CodeSandBox https://codesandbox.io/s/happy-water-fzqk8?file=/src/App.js
The below code works fine but there's hardcored variable HEIGHT which defines the height of a tab. My task is to make the height dynamic
import { useState } from 'react';
const HEIGHT = {
0: 200,
1: 400,
2: 800,
}
function App() {
const [tab, setTab] = useState(0);
const switchTab = (id) => {
setTab(id);
};
return (
<div
style={{
margin: '100px auto',
backgroundColor: 'pink',
width: '400px',
overflow: 'hidden',
height: HEIGHT[tab], // need this to be dynamic not hardcored
}}
>
<div>
{tab === 0 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 1</h2>
<input />
<button onClick={() => switchTab(1)}>Go to tab 2</button>
<p>Some text here</p>
</div>
)}
{tab === 1 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 2</h2>
<input />
<button onClick={() => switchTab(0)}>Go to tab 1</button>
<button onClick={() => switchTab(2)}>Go to tab 3</button>
<p>
Some more text here. Some more text here. Some more text here. Some more text here.
Some more text here. Some more text here. Some more text here
</p>
</div>
)}
{tab === 2 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 3</h2>
<input />
<button onClick={() => switchTab(0)}>Go to tab 1</button>
<button onClick={() => switchTab(1)}>Go to tab 2</button>
</div>
)}
</div>
</div>
);
}
What I tried:
const elRef = useRef(0);
const [height, setHeight] = useState(elRef.current.offsetHeight);
const resizeHeight = useCallback(() => {
const size = elRef.current.offsetHeight;
setHeight(size)
}, [elRef]);
<div
style={{
margin: '100px auto',
backgroundColor: 'pink',
width: '400px',
overflow: 'hidden',
height: height, // it should be the element size
}}
>
It doesn't work(( Here's the link...with the state height - undefined https://codesandbox.io/s/objective-brown-zq7ih?file=/src/App.js
Upvotes: 1
Views: 5062
Reputation: 8925
You can easily update your elRef
reference in the switchTab
handler without using useEffect
and any useCallback
hooks:
const elRef = useRef(0);
const SwitchTab = (id) => {
setTab(id);
setHeight(elRef.current.offsetHeight)
};
Now pass the elRef
to the ref
property of your target div
:
return (
<div
style={{
margin: '100px auto',
backgroundColor: 'pink',
width: '400px',
overflow: 'hidden',
height: HEIGHT[tab],
}}
>
<div ref={elRef}> // ------------------------> added here
{tab === 0 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 1</h2>
<input />
<button onClick={() => switchTab(1)}>Go to tab 2</button>
<p>Some text here</p>
</div>
)}
{tab === 1 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 2</h2>
<input />
<button onClick={() => switchTab(0)}>Go to tab 1</button>
<button onClick={() => switchTab(2)}>Go to tab 3</button>
<p>
Some more text here. Some more text here. Some more text here. Some more text here.
Some more text here. Some more text here. Some more text here
</p>
</div>
)}
{tab === 2 && (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2>Tab 3</h2>
<input />
<button onClick={() => switchTab(0)}>Go to tab 1</button>
<button onClick={() => switchTab(1)}>Go to tab 2</button>
</div>
)}
</div>
</div>
);
Upvotes: 1