如何获取作为道具传递的元素的尺寸

问题描述 投票:0回答:1

假设我有一个组件将一个元素作为名为 customHeader 的道具:

const Example = ({ children, customHeader }) => {
  ...some code  

  return (
    <>
      {customHeader ? customHeader : <div>Default Header</div>}
      {children}
    </>
  );
}

然后在我使用

Example
组件的地方执行以下操作:

<Example customHeader={<div>blah</div>}>
  <div>children</div>
</Example>

到目前为止,这是相当标准的东西,一切正常,但我遇到的问题是我希望能够通过执行类似

customHeader
的操作来获取
customHeader.clientHeight
元素的尺寸,但这行不通。当我
console.log
它时,我打印出这个对象:

{
  $$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}
}

有没有办法将作为 prop 传递的 JSX 元素转换为“普通”HTML 元素,以便我可以从中读取大量信息?

javascript reactjs react-props
1个回答
3
投票

您可以使用

cloneElement
useRef
分配给将具有您正在寻找的
aRef.current.clientHeight
的组件

我已经添加了一个简单的

<button>
来添加一些
padding
customHeader
所以你可以看到
clientHeight
改变它的价值

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>

© www.soinside.com 2019 - 2024. All rights reserved.