如何将引用附加到我使用 React.cloneElement 复制的组件

kei*_*eil 13 javascript typescript reactjs react-native react-hooks

嘿,我想将引用传递到我的组件中,这样我就可以访问所述组件上的变量,例如状态。唯一的问题是我似乎无法让它工作。它需要能够同时适用于类和函数

我从 console.log 收到的每次都是 null

  const testRef = createRef();
  console.log(testRef)
  const elementToCopy = singleScreenState.screen.peek().element;
  const Element = React.cloneElement(elementToCopy as ReactElement, { ...elementToCopy?.props, forwardRef: testRef })
Run Code Online (Sandbox Code Playgroud)

Zac*_*ber 9

在安装相关元素之前,不会填充对 React 元素的引用。所以,问题是您登录得太早了。

\n\n

我在下面的函数组件中运行了一个示例,以演示创建引用并在使用 挂载有问题的元素后记录它们useEffect

\n\n

您可能遇到的另一个问题是,根据我看到的代码,您可能在类组件的渲染函数中创建 ref ,这不会很好地工作,因为您一次无法访问 ref 变量它实际上已渲染。通常,您将 ref 变量保留为类的实例属性,以便在需要时可以访问它。

\n\n

为了使用函数组件,您需要使用forwardRef函数组件作为其定义的一部分。转发的引用可以转到useImperativeHandle钩子或另一个元素。

\n\n

有关访问参考文献的 React 文档中有更多信息:

\n\n
\n

当 ref 被传递到渲染中的元素时,对该节点的引用可以在 ref 的当前属性处访问。

\n\n

const node = this.myRef.current;

\n\n

ref 的值根据节点的类型而不同:

\n\n
    \n
  • 当在 HTML 元素上使用 ref 属性时,使用 React.createRef() 在构造函数中创建的 ref 接收底层 DOM\n 元素作为其当前属性。

  • \n
  • 当 ref 属性用于自定义类组件时,ref 对象会接收该组件的已安装实例作为其当前实例。

  • \n
  • 您不能在函数组件上使用 ref 属性,因为它们没有\xe2\x80\x99t 实例。

  • \n
\n
\n\n

最后一点是这里要注意的关键:React.ForwardRef 允许您为函数组件提供决定 ref 应该做什么的能力,因为否则 ref 无论如何都是毫无意义的。

\n\n

一般来说,在类组件中,如果你想通过它传递 ref,通常必须使用单独的 prop 名称来传递它。这里显示的方法之一:How to use React.forwardRef in a class based component?

\n\n

\r\n
\r\n
const { useRef, useEffect, useImperativeHandle } = React;\r\n\r\nconst TestFunction = React.forwardRef((props, ref) => {\r\n  useImperativeHandle(ref, () => ({\r\n    shout: () => console.log("I\'m Yelling over here!")\r\n  }));\r\n  return <div>TestFunction</div>;\r\n});\r\n\r\nclass TestComponent extends React.Component {\r\n  testFunct = () => {\r\n    console.log("testFunct works!");\r\n  };\r\n  render() {\r\n    return <div>TestComponent</div>;\r\n  }\r\n}\r\nfunction App() {\r\n  const elementRef = useRef();\r\n  const element = <div>Test</div>;\r\n  const clonedElement = React.cloneElement(element, { ref: elementRef });\r\n  const classRef = useRef();\r\n  const classElement = <TestComponent />;\r\n  const clonedClass = React.cloneElement(classElement, { ref: classRef });\r\n  const functionRef = useRef();\r\n  const functionElement = <TestFunction />;\r\n  const clonedFunction = React.cloneElement(functionElement, {\r\n    ref: functionRef\r\n  });\r\n\r\n  useEffect(() => {\r\n    console.log(\'reference to an element\',elementRef.current);\r\n    // This produces weird output in the stack overflow console.\r\n    // console.log(classRef.current);\r\n    console.log(\'function from a reference to a class component\', classRef.current.testFunct);\r\n    classRef.current.testFunct();\r\n    console.log(\'reference to a function component\',functionRef.current);\r\n    functionRef.current.shout();\r\n  });\r\n  return (\r\n    <div className="App">\r\n      {clonedElement}\r\n      {clonedClass}\r\n      {clonedFunction}\r\n    </div>\r\n  );\r\n}\r\nconst rootElement = document.getElementById("root");\r\nReactDOM.render(\r\n  <React.StrictMode>\r\n    <App />\r\n  </React.StrictMode>,\r\n  rootElement\r\n);
Run Code Online (Sandbox Code Playgroud)\r\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>\r\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>\r\n\r\n<div id="root" />
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n