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/
关注网络尖刀微信公众号随时掌握互联网精彩
- 免费好用的解压软件有哪些?
- Syncthing免费且开源的文件同步工具
- 突然宣布!六大行将集体下调
- 2023年度全国半导体行业协会秘书长联席会在南宁召开
- 代表建议:停止向未成年提供网络游戏服务
- Apple Watch选购攻略,这么买更省钱!
- 统信软件&芯动科技战略合作:工程师现场展示桌面生态算力升级
- AirPods瑕疵频现,问题出在“越南制造”?
- 517电信日|中信科移动王映民:推动5G高质量发展,助力时代变革下的数字化升级
- 海南工信厅厅长尹丽波:把握自由贸易港建设机遇 多措并举推进工业互联网发展
- 关于智能汽车,两会代表们都说了啥?
- 【大公司创新情报】中国移动与中国广电启动“5G战略”合作



微信扫码关注公众号