// 在类组件中创建 ref
class MyComponent extends Component {
ref1 =React.createRef(null) // ref1是一个对象
ref2 =null // ref2是一个函数
render=()=> {
<div>
<div ref={this.ref1}>Hello, ref1!</div>
{/* ref2是一个回调函数 */}
<div ref={(node)=>{
this.ref2 = node
console.log(this.node)
// 这里第一次打印是div,会在render之后以及componentDidMount之前执行。
// 更新后会在getSnapshotBeforeUpdate之后、componentDidUpdate之前执行
// 打印结果为null和<div>ref元素节点</div>,更新先会执行commitDetachRef方法把refs置为null,
//然后再通过commitAttachRef绑定为更新后的值
}}>Hello, ref2!</div>
</div>
}
}
// 在函数组件中创建 ref
function MyComponent() {
const childRef = useRef(null);
const divRef = useRef(null);
const handleClick = () => {
console.log(childRef.current); // 获取Child组件实例
console.log(divRef.current); // 获取div实例
};
render=()=> {
<div>
<div ref={childRef}>Hello, childRef!</div>;
<div ref={divRef}>Hello, div!</div>;
<Child ref={childRef} />
</div>
}
}
// 组件想要获取子中的 DOM 或者组件实例;
// 函数组件没有实例,只能通过 forwardRef 来获取 ref;
const Child = forwardRef((props, ref) => {
const handleClick = () => {
console.log('Hello, World!');
};
return <div ref={ref} onClick={handleClick}>Click Me</div>;
});
const Parent = () => {
const childRef = React.useRef(null);
const handleClick = () => {
console.log(childRef.current); // <div>Click Me</div>
};
return (
<div>
<Child ref={childRef} />
<button onClick={handleClick}>Get Child Ref</button>
</div>
);
};
// 高阶组件
function HOC(WrappedComponent) {
// 使用 forwardRef 来将 ref 传递给子组件
const HOC = forwardRef((props, ref) => {
return <WrappedComponent {...props} forwardedRef={ref} />;
});
return HOC;
}
// 子组件
const Child = ({ forwardedRef, ...props }) => {
// 点击事件处理函数
const handleClick = () => {
console.log('Hello, World!');
};
// 将 ref 绑定到 div 元素上
return <div ref={forwardedRef} onClick={handleClick}>Click Me</div>;
};
// 使用高阶组件封装子组件
const HocChild = HOC(Child);
// 父组件
const Parent = () => {
// 创建一个引用变量
const childRef = React.useRef(null);
// 点击事件处理函数
const handleClick = () => {
console.log(childRef.current);
};
return (
<div>
<HocChild forwardedRef={childRef} />
<button onClick={handleClick}>Get Child Ref</button>
</div>
);
};
import { useRef, useImperativeHandle, forwardRef, useState } from 'react';
// 子组件
function Son(props, ref) {
const [count, setCount] = React.useState(0);
// 使用 useImperativeHandle 来声明可以被外部调用的方法
useImperativeHandle(ref, () => ({
incrementCount() {
setCount(count + 1);
}
}));
s return <span>Count: {count}</span>;
}
const ForwardSon = forwardRef(Son);
// 父组件
function Father() {
const childRef = useRef(null);
const handleClick = () => {
childRef.current.incrementCount();
}
return (
<div>
<ForwardSon ref={childRef} />
<button onClick={handleClick}>操控子组件</button>
</div>
);
}