内容简介:Refs 转发:将父组件创建的 ref 传递给子组件的某个dom元素(或组件)。让父组件可以直接操作该dom元素(或组件)一开始使用该技术的时候,分不清 传 自定义 ref prop 和 转发ref 有什么区别,本文稍微探讨下InputChild 为子组件,App 为父组件
前言
Refs 转发:将父组件创建的 ref 传递给子组件的某个dom元素(或组件)。让父组件可以直接操作该dom元素(或组件)
一开始使用该技术的时候,分不清 传 自定义 ref prop 和 转发ref 有什么区别,本文稍微探讨下
Demo: 父组件触发子组件的input元素获取焦点
InputChild 为子组件,App 为父组件
const InputChild = (props) => ( <input></input> )); class App extends React.Component { constructor() { super() this.icRef = React.createRef(); } render () { <InputChild ref={this.icRef}>Click me!</InputChild>; } }
按上面的操作,icRef 拿到的是 InputChild 组件,拿不到 InputChild 下的 input 元素。
比如想在父组件上让 InputChild 的 input 获取焦点,是不行的。
this.icRef.current.focus() //报错
InputChild 创建 ref 绑定 input
在 InputChild 上,利用 inputRef = React.createRef()
绑定 input,
然后父组件通过 ref.current.inputRef.current.focus()
获取焦点
class InputChild extends React.Component{ constructor(){ super() this.inputRef = React.createRef() } render(){ return ( <input ref={this.inputRef}></input> ) } } class App extends React.Component { constructor() { super() this.icRef = React.createRef(); } render () { <InputChild ref={this.icRef}>Click me!</InputChild>; } }
this.ref.current.inputRef.current.focus() // input 获取焦点
Refs 转发
函数组件使用
const InputChild = React.forwardRef((props, ref) => ( <input ref={ref}> </input> )); class App extends React.Component { constructor() { super() this.icRef = React.createRef(); } handleClick = () => { this.icRef.current.focus() } render () { <> <button onClick={this.handleClick}>Learn React</button> <InputChild ref={this.icRef}>Click me!</InputChild>; </> } }
点击 button 后,input 可以获取到焦点
Class 组件使用
function refProps(Component) { return React.forwardRef((props, ref) => { return <Component {...props} forwardedRef={ref} />; }); } @refProps class InputChild extends React.Component{ render(){ const { forwardedRef } = this.props; return ( <input ref={forwardedRef}></input> ) } }
效果同上,但是这里是 将 ref 绑定到新的prop上
尚未知道还有没有更好的做法
自定义 prop 属性
其实也可以直接定义一个 非ref 的prop,如下
class InputChild extends React.Component{ render(){ const { forwardedRef } = this.props; return ( <input ref={forwardedRef}></input> ) } } // 父组件使用 <InputChild forwardRef={this.ref} />
注意:函数式组件不能提供ref,否则对ref的访问将会失败,只能用 React.forwardRef()
传递 ref
效果是一样,但是对于上层使用者(不知道子组件代码的)来说, 第一想法是用 ref 绑定子组件而不是其他额外prop (forwardRef)
高阶组件上使用 refs 转发
需求:我们有一个 LogProps 高阶组件用于记录 props log,但是对 上层用户是不可见的
用户使用 <Child ref={this.ref}/>
。 ref 拿到的应该是 Child 而不是 高阶组件
错误使用
function logProps(WrappedComponent) { class LogProps extends React.Component { componentDidUpdate(prevProps) { console.log('old props:', prevProps); console.log('new props:', this.props); } render() { return <WrappedComponent {...this.props} />; } } return LogProps; } @logProps class Child extends React.Component{ render(){ <div/> } } <Child ref={this.ref}>Click me!</Child>;
this.ref
拿到的是 LogProps 组件,ref prop被消化,不会被传递到 Child
正确使用
function logProps(WrappedComponent) { class LogProps extends React.Component { componentDidUpdate(prevProps) { console.log('old props:', prevProps); console.log('new props:', this.props); } render() { const {forwardedRef, ...rest} = this.props; // Assign the custom prop "forwardedRef" as a ref return <WrappedComponent ref={forwardedRef} {...rest} />; } } return React.forwardRef((props, ref) => { return <LogProps {...props} forwardedRef={ref} />; }); } @logProps class Child extends React.Component{ render(){ <div/> } } <Child ref={this.ref}>Click me!</Child>;
this.ref
拿到的是 Child 组件
Child 组件使用高阶组件,并且父组件的 ref 要绑定 Child下的 input元素
在以上的基础上,再转发一次
const InputChild = React.forwardRef((props, ref) => ( <input ref={ref}> </input> )); // 使用高阶组件对其进行封装 export default logProps(InputChild); // 父组件中 <Child ref={this.ref}>Click me!</Child>;
父组件 this.ref.current.focus() 即可让 input 获取焦点
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
VISUAL BASIC 6.0 WINDOWS API讲座
王国荣 / 人民邮电出版社 / 1999-06-01 / 76.00元
本书全面介绍了在Visual Basic 6.0中如何调用Windows API的技术,特别是结合读者在应用中经常遇到的具体问题编写了许多应用范例,书中还给出了API函数的速查表。本书主要内容包括: Windows API的基本概念和调用方法,资源文件的使用,Windows的消息系统及其应用,API在绘图中的应用,多媒体文件的播放,特殊命令按钮的制作等。 本书适用于已熟悉Visual Basic的一起来看看 《VISUAL BASIC 6.0 WINDOWS API讲座》 这本书的介绍吧!