使用 useImperativeHandle 后,可以让父、子组件分别有自己的 ref(以避免子会修改父的 DOM),通过 React.forwardRef 将父组件的 ref 转发(透传)过来,通过 useImperativeHandle 方法来自定义开放给父组件的 current。
一般来说
useImperativeHandle 是与 forwardRef 一起使用
useImperativeHanlde(ref, ()=>{}, [])
目的就是封装一个 ref, 给父组件来使用自己的 ref。ref 的内容由 ()=>{} 这个返回对象的回调来控制。而 [] 依赖项可以设置返回的对象 ref.current 以什么依赖发生改变。
import React, {
useState,
useRef,
useImperativeHandle,
useCallback
} from 'react';
import ReactDOM from 'react-dom';
const FancyInput = React.forwardRef((props, ref) => {
const [ fresh, setFresh ] = useState(false)
const attRef = useRef();
useImperativeHandle(ref, () => ({
attRef,
fresh
}), [ fresh ]);
const handleClick = useCallback(() => {
attRef.current++;
}, []);
return (
<div>
{attRef.current}
<button onClick={handleClick}>Fancy</button>
<button onClick={() => setFresh(!fresh)}>刷新</button>
</div>
)
});
const App = props => {
const fancyInputRef = useRef();
return (
<div>
<FancyInput ref={fancyInputRef} />
<button
onClick={() => console.log(fancyInputRef.current)}
>父组件访问子组件的实例属性</button>
</div>
)
}
ReactDOM.render(<App />, root);