We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2023年初的计划都实现了吗?呵呵,不管怎么样,迄今为止我博客坚持时间也马上10年了,2014年,我创建了本博客,如今马上2024年了,本博客也马上10年了,10年见证了互联网的兴起,鼎盛。其实坚持做一件事不容易,希望大家多多支持。本文主要总结一下React 的几种 Ref 的使用,之前也有文章介绍过react父组件调用子组件的方法小结,其实这里介绍了一些ref的用法,但是不是很全面,本文再次总结一下,作为2023的尾声!
一. String Refs
class App extends React.Component { constructor(props) { super(props) } componentDidMount() { setTimeout(() => { // 2. 通过 this.refs.xxx 获取 DOM 节点 this.refs.textInput.value = 'new value' }, 2000) } render() { // 1. ref 直接传入一个字符串 return ( <div> <input ref="textInput" value='value' /> </div> ) } } root.render(<App />);
二、回调 Refs
class App extends React.Component { constructor(props) { super(props) } componentDidMount() { setTimeout(() => { // 2. 通过实例属性获取 DOM 节点 this.textInput.value = 'new value' }, 2000) } render() { // 1. ref 传入一个回调函数 // 该函数中接受 React 组件实例或 DOM 元素作为参数 // 我们通常会将其存储到具体的实例属性(this.textInput) return ( <div> <input ref={(element) => { this.textInput = element; }} value='value' /> </div> ) } } root.render(<App />);
三、 createRef
class App extends React.Component { constructor(props) { super(props) // 1. 使用 createRef 创建 Refs // 并将 Refs 分配给实例属性 textInputRef,以便在整个组件中引用 this.textInputRef = React.createRef(); } componentDidMount() { setTimeout(() => { // 3. 通过 Refs 的 current 属性进行引用 this.textInputRef.current.value = 'new value' }, 2000) } render() { // 2. 通过 ref 属性附加到 React 元素 return ( <div> <input ref={this.textInputRef} value='value' /> </div> ) } }
这是最被推荐使用的方式。
这个我开头说了,可以用作父组件调用子组件函数来使用。
例如如下一个例子:
class Input extends React.Component { constructor(props) { super(props) this.textInputRef = React.createRef(); } handleFocus() { this.textInputRef.current.focus(); } render() { return <input ref={this.textInputRef} value='value' /> } } class App extends React.Component { constructor(props) { super(props) this.inputRef = React.createRef(); } componentDidMount() { setTimeout(() => { this.inputRef.current.handleFocus() }, 2000) } render() { return ( <div> <Input ref={this.inputRef} value='value' /> </div> ) } }
具体父子组件hooks或者component 可以看我之前文章https://www.haorooms.com/post/react_class_hooks_dy
上面例子中,假如input我们用hooks实现,那么就会报错,如何input用hooks呢? React 提供了 forwardRef 这个 API,我们直接看使用示例:
// 3. 子组件通过 forwardRef 获取 ref,并通过 ref 属性绑定 React 元素 const Child = forwardRef((props, ref) => ( <input ref={ref} placeholder="value" /> )); class Parent extends React.Component { constructor(props) { super(props) // 1. 创建 refs this.inputRef = React.createRef(); } componentDidMount() { setTimeout(() => { // 4. 使用 this.inputRef.current 获取子组件中渲染的 DOM 节点 this.inputRef.current.value = 'new value' }, 2000) } render() { // 2. 传给子组件的 ref 属性 return <Child ref={this.inputRef} /> } }
这样就可以了
现在我们看下 createRef 的源码,源码的位置在 /packages/react/src/ReactCreateRef.js,代码其实很简单,就只是返回了一个具有 current 属性的对象:
// 简化后 export function createRef() { const refObject = { current: null, }; return refObject; }
在渲染的过程中,refObject.current 会被赋予具体的值。
那 forwardRef 源码呢?源码的位置在 /packages/react/src/ReactForwardRef.js,代码也很简单:
// 简化后 const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); export function forwardRef(render) { const elementType = { $$typeof: REACT_FORWARD_REF_TYPE, render, }; return elementType; }
但是要注意这里的 $$typeof,尽管这里是 REACT_FORWARD_REF_TYPE,但最终创建的 React 元素的 $$typeof 依然为 REACT_ELEMENT_TYPE。
2023年最后一篇文章,祝大家新年快乐,2024心想事成吧! 今天就先到这里。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
2023年初的计划都实现了吗?呵呵,不管怎么样,迄今为止我博客坚持时间也马上10年了,2014年,我创建了本博客,如今马上2024年了,本博客也马上10年了,10年见证了互联网的兴起,鼎盛。其实坚持做一件事不容易,希望大家多多支持。本文主要总结一下React 的几种 Ref 的使用,之前也有文章介绍过react父组件调用子组件的方法小结,其实这里介绍了一些ref的用法,但是不是很全面,本文再次总结一下,作为2023的尾声!
ref的三种调用方式
一. String Refs
二、回调 Refs
三、 createRef
这是最被推荐使用的方式。
ref可以起到调用子级组件的作用
这个我开头说了,可以用作父组件调用子组件函数来使用。
例如如下一个例子:
具体父子组件hooks或者component 可以看我之前文章https://www.haorooms.com/post/react_class_hooks_dy
forwardRef
上面例子中,假如input我们用hooks实现,那么就会报错,如何input用hooks呢?
React 提供了 forwardRef 这个 API,我们直接看使用示例:
这样就可以了
相关源码解析
现在我们看下 createRef 的源码,源码的位置在 /packages/react/src/ReactCreateRef.js,代码其实很简单,就只是返回了一个具有 current 属性的对象:
在渲染的过程中,refObject.current 会被赋予具体的值。
那 forwardRef 源码呢?源码的位置在 /packages/react/src/ReactForwardRef.js,代码也很简单:
但是要注意这里的 $$typeof,尽管这里是 REACT_FORWARD_REF_TYPE,但最终创建的 React 元素的 $$typeof 依然为 REACT_ELEMENT_TYPE。
小结
2023年最后一篇文章,祝大家新年快乐,2024心想事成吧!
今天就先到这里。
The text was updated successfully, but these errors were encountered: