useRef
useRef 返回一个可变的ref对象,其.current属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
基本用法,设置焦点
function TextInputWithFocusButton() {
const inputEl: MutableRefObject<any> = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
在组件的整个生命周期里,inputEl.current都是存在的,这扩展了useRef本身的用途,可以使用useRef维护类似于class.component中实例属性的变量。
类似于class.component中实例属性的变量
const Count = () => {
const [count, setCount] = useState(0);
const prevCountRef = useRef(count);
const prevCount = prevCountRef.current;
useEffect(() =>{
prevCountRef.current = count;
console.log('useEffect:', prevCountRef)
}, [count]);
return (
<div>
<button onClick={() => { setCount( count + 1 ) }}>加1</button>
<p>count: {count}</p>
<p>prevCount: {prevCount}</p>
</div>
)
}
useImperativeHandle
建议useImperativeHandle和forwardRef同时使用,减少暴露给父组件的属性,避免使用 ref 这样的命令式代码
import { useRef,forwardRef,MutableRefObject,useImperativeHandle,Ref} from "react";
//只暴露value、getType、focus给父级
const InputEl = forwardRef((props: {}, ref: Ref<any>): JSX.Element=>{
const inputEl: MutableRefObject<any> = useRef();
useImperativeHandle(ref, ()=>({//第一个参数:暴露哪个ref;第二个参数:暴露什么
value: (inputEl.current as HTMLInputElement).value,
getType: () => (inputEl.current as HTMLInputElement).type,
focus: () => (inputEl.current as HTMLInputElement).focus()
}));
return(
<input ref={inputEl} type="text" {...props}/>
)
})
//暴露整个input节点给父级
const InputEl = forwardRef((props: {}, ref: Ref<any>): JSX.Element=>{
return(
<input ref={ref} type="text" {...props}/>
)
});
//父级
function InputWithFocusButton() {
const inputEl: MutableRefObject<any> = useRef(null);
function onButtonClick() {
console.log('子组件input的对象:', inputEl.current);
inputEl.current.focus();
};
return (
<>
<InputEl ref={inputEl} />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
通过forwardRef
,父组件获取子组件的ref,子组件在暴露ref中,限制暴露的一些参数
作者:fen同学
链接:https://juejin.im/post/5d8f478751882509563a03b3
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程
本文著作权归作者所有,如若转载,请注明出处
转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com