React.forwardRef怎么样使用,作用是什么
Admin 2022-07-04 群英技术资讯 862 次浏览
这篇文章给大家介绍了“React.forwardRef怎么样使用,作用是什么”的相关知识,讲解详细,步骤过程清晰,有一定的借鉴学习价值,因此分享给大家做个参考,感兴趣的朋友接下来一起跟随小编看看吧。之前使用react.forwardRef始终无法应用于react高阶组件中,最近终于捣鼓出来了,于是记录下来。关键点就是React.forwardRef的API中ref必须指向dom元素而不是React组件。
下面就是应用到React组件的错误示例:
const A=React.forwardRef((props,ref)=><B {...props} ref={ref}/>)
这就是我之前经常犯的错误, 这里的ref是无法生效的。
前面提到ref必须指向dom元素,那么正确方法就应用而生:
const A=React.forwardRef((props,ref)=>(
<div ref={ref}>
<B {...props} />
</div>
))
父组件获取子组件中Dom元素实例

import React, { useRef } from 'react';
import Content from './content';
const Home = () => {
// 创建一个Ref对象
const connectRef = useRef(null);
const handleFoucus = () => {
const _ref = connectRef.current;
_ref.focus();
};
return (
<div>
<button onClick={() => handleFoucus()}>
使用子组件中DOM元素的方法
</button>
<Content ref={connectRef} />
</div>
);
};
export default Home;
import React, { forwardRef } from 'react';
/**
* forwardRef包裹后,ref会作为第二个参数,接收传进来的ref属性
* e.g.
* <Content count={count} user={user} ref={connectRef}>
*
* @param props - {count, user}
* @param ref - connectRef
* */
const Content = (props, ref) => {
return (
<div>
{/* 把ref绑定给传进来的ref ≈ ref={connectRef} */}
<input type="password" ref={ref} />
</div>
)
};
export default forwardRef(Content);

import React, { useRef } from 'react';
import Content from './content';
const Home = () => {
// 创建一个Ref对象
const connectRef = useRef(null);
const handleAdd = () => {
const _ref = connectRef.current;
const { count } = _ref.state;
_ref.setState({
count: count + 1
})
};
return (
<div>
<button onClick={() => handleAdd()}>
使用子组件中class组件的属性和方法
</button>
<Content ref={connectRef} />
</div>
);
};
export default Home;
import React, { forwardRef } from 'react';
import Header from './header';
import Footer from './footer';
/**
* forwardRef包裹后,ref会作为第二个参数,接收传进来的ref属性
* e.g.
* <Content count={count} user={user} ref={connectRef}>
*
* @param props - {count, user}
* @param ref - connectRef
* */
const Content = (props, ref) => {
return (
<div>
{/* 把ref绑定给传进来的ref ≈ ref={connectRef} */}
<Header ref={ref} /> {/* class组件 */}
{/* <Footer ref={ref} /> 函数组件是没有实例的,所以connectRef.current: null */}
</div>
)
};
export default forwardRef(Content)
import React from 'react';
export default class Header extends React.Component {
state = {
count: 0
};
render() {
return (
<div>
{this.state.count}
</div>
)
}
};
高阶组件会把所有接收到的props,传递给被包装的组件(透传)
ref 和 key 类似,不是一个prop,所以不会透传,ref会绑定到外层的包装容器上
/*
处理ref
e.g. Hoc1(Hoc2(Content))
<Content ref={myRef} /> 给Content绑定的ref会绑定到Hoc1上,且不会继续向下传递
第一种方法 React.forwardRef ===============
在 Hoc1外面 用React.forwardRef()对ref做处理,用props来传递ref
0. 在高阶组件外面包裹forwardRef,拦截获取ref,增加一个props(xxx={ref}),真实组件通过props.xxx获取
1. 使用时传 ref={XXXX} // 和第二种方法不同的地方
2. 用forwardRef的第二个参数获取 ref
3. 增加一个新的props,用来向下转发ref e.g. forwardedRef={ref}
4. 真实组件中绑定 ref={props.forwardedRef}
const Home = (props) => {
const connectRef = useRef(null);
return (
<div>
<Content ref={connectRef} />
</div>
);
};
// 被包装组件
const Content = (props) => {
return (
<div>
<input type="password" ref={props.forwardedRef} />
</div>
);
};
// forwardRef的第二个入参可以接收ref,在Hoc外层对ref做处理
export default React.forwardRef((props, ref) => {
const Wrapper = React.memo(Content); // Hoc
// forwardRef包裹的是Wrapper
// 需要在Wrapper中把ref向下传递给真实组件
// Wrapper中增加一个props属性,把ref对象作为props传给子组件
return <Wrapper {...props} forwardedRef={ref} />;
});
第二种方法 ==========
0. 使用时就用一个props来保存ref
1. 使用时传 xxx={ref} // 和第一种方法的不同点
2. 真实组件中绑定 ref={props.xxx}
const Home = (props) => {
const connectRef = useRef(null);
return (
<div>
<Content forwardedRef={connectRef} />
</div>
);
};
// 定义高阶组件
export const Hoc = (WrappedComponent) => {
class Wrapper extends React.Component {
render() {
return <WrappedComponent {...props} />
}
}
}
// 被包装的组件
const Content = (props) => {
return (
<div>
<input type="password" ref={props.forwardedRef} />
</div>
);
};
// 包装过程
export default Hoc(Content);
* */
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文给大家分享关于JavaScript调试的内容,这里介绍的是JavaScript快速调的两个方法,对大家学习了解JavaScript怎样调试有一定的帮助,感兴趣的朋友就继续往下看吧。
这篇文章给大家分享的是用vue怎样实现压缩图片再上传的功能。小编觉得挺实用的,很多场景都可以应用,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
轮播图是现在很多网站平台都会应用的一种展现方式,通过定时或者鼠标点击就能够切换看到多张图片,很多商都会将轮播图作为产品展示,这样的效果是用户就能更容易获取商品信息。那么轮播图是如何实现的呢?下面就以基于JavaScript实现的简单轮播图为例,为大家简单介绍下。
这篇文章给大家分享的JS实现动态添加圆圈序号效果。小编觉得挺实用的,而且这种效果的效果也比较美观,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
vue-router安装步骤是什么,使用是怎样?一些朋友可能会遇到这方面的问题,对此在下文小编向大家来讲解一下,内容详细,易于理解,希望大家阅读完这篇能有收获哦,有需要的朋友就往下看吧!
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008