如何访问在渲染中设置的 ref

Sim*_*mon 6 javascript reactjs react-native

嗨,我有一些以下代码:

class First extends Component {
 constructor(props){super(props)}

 myfunction = () => { this.card //do stuff}

 render() {
  return(
  <Component ref={ref => (this.card = ref)} />
 )}
}
Run Code Online (Sandbox Code Playgroud)

为什么我无法访问cardin myfunction. 它告诉我它是未定义的。我尝试this.card = React.createRef();在构造函数中设置 a ,但这也不起作用。

Yua*_*ang 0

你快到了,你的子组件很可能没有使用 a forwardRef,因此出现错误(来自React 文档)。ref(与 类似key)默认情况下不能直接访问:

\n\n
const MyComponent = React.forwardRef((props, ref) => (\n  <button ref={ref}>\n    {props.children}\n  </button>\n));\n\n// \xe2\x98\x9d\xef\xb8\x8f now you can do <MyComponent ref={this.card} />\n
Run Code Online (Sandbox Code Playgroud)\n\n

ref最终,它是一个 DOMNode,并且应该这样对待,它只能引用将要渲染的 HTML 节点。您将在一些较旧的库中看到它,如果它让您感到困惑,它innerRef也可以工作而不需要:forwardRef

\n\n
const MyComponent = ({ innerRef, children }) => (\n  <button ref={innerRef}>\n    {children}\n  </button>\n));\n\n// \xe2\x98\x9d\xef\xb8\x8f now you can do <MyComponent innerRef={this.card} />\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,如果它是您创建的组件,您将需要确保通过forwardRef(或innerRef)等效项传递 ref。如果您使用的是第三方组件,您可以测试它是否使用refinnerRef。如果没有,将其包裹在 a 周围div,虽然不理想,但可能就足够了(但它并不总是有效):

\n\n
render() {\n  return (\n    <div ref={this.card}>\n      <MyComponent />\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,对 refs 和生命周期方法进行一些解释,这可能会帮助您更好地理解上下文。

\n\n

渲染不保证refs已设置:

\n\n

这是一种先有鸡还是先有蛋的问题:您希望组件使用指向节点的ref执行某些操作,但 React 本身尚未创建该节点。所以,我们能做些什么?

\n\n

有两种选择:

\n\n

1) 如果您需要传递 ref 来渲染其他内容,请首先检查它是否有效:

\n\n
const MyComponent = React.forwardRef((props, ref) => (\n  <button ref={ref}>\n    {props.children}\n  </button>\n));\n\n// \xe2\x98\x9d\xef\xb8\x8f now you can do <MyComponent ref={this.card} />\n
Run Code Online (Sandbox Code Playgroud)\n\n

2)如果你想要做某种副作用,componentDidMount将保证ref被设置:

\n\n
componentDidMount() {\n  if (this.card.current) {\n      console.log(this.card.current.classList);\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这能让它更清楚!

\n