Let's say I have a component that takes an element as a prop called customHeader:
const Example = ({ children, customHeader }) => {
...some code
return (
<>
{customHeader ? customHeader : <div>Default Header</div>}
{children}
</>
);
}
Then where I use the Example
component I do the following:
<Example customHeader={<div>blah</div>}>
<div>children</div>
</Example>
So far this is fairly standard stuff and everything is working but the problem I have is that I want to be able to grab the dimensions of the customHeader
element by doing something like customHeader.clientHeight
but that won't work. When I console.log
it I get this object printed out:
{
$$typeof: Symbol(react.element)
key: ".0"
props: {children: 'Blah'}
ref: null
type: "div"
_owner: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
_store: {validated: false}
}
Is there a way to convert a JSX element that is passed as a prop to an "normal" HTML element so I can read a bunch of information off it?
You could use cloneElement
to assign an useRef
to the component that will have the aRef.current.clientHeight
you're looking for
I've added a simple <button>
to add some padding
to the customHeader
so you can see the clientHeight
change it's value
const { useEffect, useRef, useState } = React;
const Example = ({ children, customHeader }) => {
const aRef = useRef();
useEffect(() => {
if (aRef.current) {
const clientHeight = aRef.current.clientHeight;
console.log(`ClientHeight: ${clientHeight}`);
}
}, [ customHeader ]);
return (
<React.Fragment>
{children}
{
(customHeader)
? React.cloneElement(customHeader, { ref: aRef })
: <div>Default Header</div>
}
</React.Fragment>
);
}
const App = () => {
/* Demo purpose only */
const [customHeaderPadding, setCustomHeaderPadding] = useState(0);
const toggleCustomHeaderPadding = () => {
const newValue = (customHeaderPadding === 0) ? 50 : 0;
setCustomHeaderPadding(newValue);
}
/* Demo purpose only */
return (
<Example customHeader={<div style={{ padding: customHeaderPadding }}>blah</div>}>
<button onClick={toggleCustomHeaderPadding}>{'Toggle Padding'}</button>
<div>children</div>
</Example>
);
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>