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/

随时掌握互联网精彩
- 多邻国猫头鹰有望复活:需要全球用户共同支援!
- 黑客自称已窃取200万个OpenAI账户密码 尽管真实性较低但OpenAI已开始调查
- 加币兑换人民币汇率2024年2月13日
- 欧元人民币汇率2023年8月9日
- 马斯克计划未来数月裁掉推特75%员工;律师调查GitHub Copilot版权侵犯问题;Firefox 106 发布|极客头条
- Go 临界资源的安全问题(引入同步异步处理)
- InfluxDB的优势是什么?
- “旧瓶装新酒”成谜?没考虑好劝你别买iPhone SE3!
- 《2022年美国情报界年度威胁评估》7大威胁详解!
- 破局十四五:中国5G向前,SA向下
- 百万人瞩目,盛况空前!统信UOS生态大会成功举办
- 云时代下,移动云揭秘数据库“新解”