React新文档:不要滥用Ref哦~
作者:卡颂
简介:《React技术揭秘》作者
来源:SegmentFault 思否社区
大家好,我卡颂。
React新文档有个很有意思的细节:useRef、useEffect这两个API的介绍,在文档中所在的章节叫Escape Hatches(逃生舱)。
显然,正常航行时是不需要逃生舱的,只有在遇到危险时会用到。
如果开发者过多依赖这两个API,可能是误用。
在React新文档:不要滥用effect哦中我们谈到useEffect的正确使用场景。
今天,我们来聊聊Ref的使用场景。
为什么是逃生舱?
先思考一个问题:为什么ref、effect被归类到逃生舱中?
这是因为二者操作的都是脱离React控制的因素。
effect中处理的是副作用。比如:在useEffect中修改了document.title。
document.title不属于React中的状态,React无法感知他的变化,所以被归类到effect中。
同样,使DOM聚焦需要调用element.focus(),直接执行DOM API也是不受React控制的。
虽然他们是脱离React控制的因素,但为了保证应用的健壮,React也要尽可能防止他们失控。
失控的Ref
对于Ref,什么叫失控呢?
首先来看不失控的情况:
执行ref.current的focus、blur等方法
执行ref.current.scrollIntoView使element滚动到视野内
执行ref.current.getBoundingClientRect测量DOM尺寸
执行ref.current.remove移除DOM
执行ref.current.appendChild插入子节点
export default function Counter() { const [show, setShow] = useState(true); const ref = useRef(null); return ( <div>
<button
onClick={() => {
setShow(!show);
}}>
Toggle with setState </button>
<button
onClick={() => {
ref.current.remove();
}}>
Remove from the DOM </button>
{show && <p ref={ref}>Hello world</p>} </div>
);
}

如何限制失控
高阶组件
低阶组件
function MyInput(props) { return <input {...props} />;
}
function MyInput(props) { const ref = useRef(null); return <input ref={ref} {...props} />;
}
function Form() { return ( <>
<MyInput/>
</>
)
}
function MyInput(props) { return <input {...props} />;
}function Form() { const inputRef = useRef(null); function handleClick() {
inputRef.current.focus();
} return ( <>
<MyInput ref={inputRef} />
<button onClick={handleClick}>
input聚焦 </button>
</>
);
}点击后,会报错:

人为取消限制
const MyInput = forwardRef((props, ref) => { return <input {...props} ref={ref} />;
});function Form() { const inputRef = useRef(null); function handleClick() {
inputRef.current.focus();
} return ( <>
<MyInput ref={inputRef} />
<button onClick={handleClick}>
Focus the input </button>
</>
);
}
useImperativeHandle
const MyInput = forwardRef((props, ref) => { const realInputRef = useRef(null); useImperativeHandle(ref, () => ({ focus() {
realInputRef.current.focus();
},
})); return <input {...props} ref={realInputRef} />;
});
{ focus() {
realInputRef.current.focus();
},
}
总结


关注公众号:拾黑(shiheibook)了解更多
赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

随时掌握互联网精彩
- FytSoaCms基于.NET开源、免费、功能强大的Cms建站系统
- 四槽厚“巨无霸”?疑似RTX 4090 Ti原型显卡照片现身
- 2022年能源领域前沿科技发展态势及2023年趋势展望
- 【有料视频】用不惯Win 11?教你一招退回Win 10!
- 国内何时能用上手机eSIM卡?工信部回应了
- 工信部:上半年中小微企业享受新增减税降费及退税缓税缓费近1.8万亿元
- 社区精选 | Wuzzle,进行基于 webpack 的 JS 转译
- 手机“双芯”渐成趋势,第二芯解锁差异化体验
- 6G将走向人机物灵充分联结、虚实结合、智慧涌现的泛在智简网络
- “天才陨落”:91年,30岁 | 腾讯确认天美F1工作室毛星云离世
- 微信将新增更多玩法和功能;抖音回应 “ 上线抖音支付 ”;消息称百度急叫停与郑爽合作原创栏目|Do早报
- 中国移动4亿元软跳纤产品集采结果:中兴新地、中天、通鼎等10家中标