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

Avi*_*Avi 1 javascript reactjs react-props

假设我有一个组件,它将一个元素作为名为 customHeader 的 prop:

\n
const Example = ({ children, customHeader }) => {\n  ...some code  \n\n  return (\n    <>\n      {customHeader ? customHeader : <div>Default Header</div>}\n      {children}\n    </>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后,在使用该Example组件的地方,我执行以下操作:

\n
<Example customHeader={<div>blah</div>}>\n  <div>children</div>\n</Example>\n
Run Code Online (Sandbox Code Playgroud)\n

到目前为止,这是相当标准的东西,一切正常,但我遇到的问题是,我希望能够customHeader通过执行类似的操作来获取元素的尺寸customHeader.clientHeight,但这是行不通的。当我console.log这样做时,我打印出了这个对象:

\n
{\n  $$typeof: Symbol(react.element)\n  key: ".0"\n  props: {children: 'Blah'}\n  ref: null\n  type: "div"\n  _owner: FiberNode {tag: 0, key: null, stateNode: null, elementType: \xc6\x92, type: \xc6\x92, \xe2\x80\xa6}\n  _store: {validated: false}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

0st*_*ne0 5

您可以使用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"));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • `{ref: aRef}` 就足够了;您不需要将 ref 设为函数。 (2认同)
  • [^^](/sf/ask/5303012711/#comment133640153_75757423)正如Unmitigated所说,上面使用的没有理由将其作为回调引用。但是你*可以*使用回调引用*而不是*效果回调:https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node (2认同)