ReactforwardRef的使⽤⽅法及注意点
之前使⽤react.forwardRef始终⽆法应⽤于react⾼阶组件中,最近终于捣⿎出来了,于是记录下来。关键点就是React.forwardRef的API中ref必须指向dom元素⽽不是React组件。
React.forwardRef使⽤⽰例
下⾯就是应⽤到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>
))
作⽤与注意点
1. ⽗组件创建⼀个ref对象,绑定给⼦组件中的Dom元素或class组件
2. 函数组件是没有实例的
3. ⾼阶组件需做特殊处理
⽗组件获取⼦组件中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);
⽗组件获取⼦组件中class组件实例
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} />
);
};
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} */}
react面试题ref概念
<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>
{unt}
</div>
)
}
};
⾼阶组件中的特殊情况
会把所有接收到的props,传递给被包装的组件(透传)
ref 和 key 类似,不是⼀个prop,所以不会透传,ref会绑定到外层的包装容器上
/*
处理ref
< Hoc1(Hoc2(Content))
<Content ref={myRef} /> 给Content绑定的ref会绑定到Hoc1上,且不会继续向下传递
第⼀种⽅法 React.forwardRef ===============
在 Hoc1外⾯⽤React.forwardRef()对ref做处理,⽤props来传递ref
0. 在⾼阶组件外⾯包裹forwardRef,拦截获取ref,增加⼀个props(xxx={ref}),真实组件通过获取
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 = (Content);  // Hoc
// forwardRef包裹的是Wrapper
// 需要在Wrapper中把ref向下传递给真实组件
// Wrapper中增加⼀个props属性,把ref对象作为props传给⼦组件
return <Wrapper {...props} forwardedRef={ref} />;
});
第⼆种⽅法 ==========
0. 使⽤时就⽤⼀个props来保存ref
1. 使⽤时传 xxx={ref}  // 和第⼀种⽅法的不同点
2. 真实组件中绑定 ref={}
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);
* */
以上就是React forwardRef的使⽤⽅法及注意点的详细内容,更多关于React forwardRef使⽤的资料请关注其它相关⽂章!