摘要:可以看到,这样不仅没有占用组件自己的,也不需要手写回调函数进行处理,这些处理都压缩成了一行。效果通过拿到周期才执行的回调函数。实现等价于的回调仅执行一次时,因此直接把回调函数抛出来即可。
1 引言
上周的 精读《React Hooks》 已经实现了对 React Hooks 的基本认知,也许你也看了 React Hooks 基本实现剖析(就是数组),但理解实现原理就可以用好了吗?学的是知识,而用的是技能,看别人的用法就像刷抖音一样(哇,饭还可以这样吃?),你总会有新的收获。
这篇文章将这些知识实践起来,看看广大程序劳动人民是如何发掘 React Hooks 的潜力的(造什么轮子)。
首先,站在使用角度,要理解 React Hooks 的特点是 “非常方便的 Connect 一切”,所以无论是数据流、Network,或者是定时器都可以监听,有一点 RXJS 的意味,也就是你可以利用 React Hooks,将 React 组件打造成:任何事物的变化都是输入源,当这些源变化时会重新触发 React 组件的 render,你只需要挑选组件绑定哪些数据源(use 哪些 Hooks),然后只管写 render 函数就行了!
2 精读参考了部分 React Hooks 组件后,笔者按照功能进行了一些分类。
由于 React Hooks 并不是非常复杂,所以就不按照技术实现方式去分类了,毕竟技术总有一天会熟练,而且按照功能分类才有持久的参考价值。DOM 副作用修改 / 监听
做一个网页,总有一些看上去和组件关系不大的麻烦事,比如修改页面标题(切换页面记得改成默认标题)、监听页面大小变化(组件销毁记得取消监听)、断网时提示(一层层装饰器要堆成小山了)。而 React Hooks 特别擅长做这些事,造这种轮子,大小皆宜。
由于 React Hooks 降低了高阶组件使用成本,那么一套生命周期才能完成的 “杂耍” 将变得非常简单。
下面举几个例子:
修改页面 title效果:在组件里调用 useDocumentTitle 函数即可设置页面标题,且切换页面时,页面标题重置为默认标题 “前端精读”。
useDocumentTitle("个人中心");
实现:直接用 document.title 赋值,不能再简单。在销毁时再次给一个默认标题即可,这个简单的函数可以抽象在项目工具函数里,每个页面组件都需要调用。
function useDocumentTitle(title) { useEffect( () => { document.title = title; return () => (document.title = "前端精读"); }, [title] ); }
在线 Demo
监听页面大小变化,网络是否断开效果:在组件调用 useWindowSize 时,可以拿到页面大小,并且在浏览器缩放时自动触发组件更新。
const windowSize = useWindowSize(); return页面高度:{windowSize.innerWidth};
实现:和标题思路基本一致,这次从 window.innerHeight 等 API 直接拿到页面宽高即可,注意此时可以用 window.addEventListener("resize") 监听页面大小变化,此时调用 setValue 将会触发调用自身的 UI 组件 rerender,就是这么简单!
最后注意在销毁时,removeEventListener 注销监听。
function getSize() { return { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }; } function useWindowSize() { let [windowSize, setWindowSize] = useState(getSize()); function handleResize() { setWindowSize(getSize()); } useEffect(() => { window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, []); return windowSize; }
在线 Demo
动态注入 css效果:在页面注入一段 class,并且当组件销毁时,移除这个 class。
const className = useCss({ color: "red" }); returnText.;
实现:可以看到,Hooks 方便的地方是在组件销毁时移除副作用,所以我们可以安心的利用 Hooks 做一些副作用。注入 css 自然不必说了,而销毁 css 只要找到注入的那段引用进行销毁即可,具体可以看这个 代码片段。
DOM 副作用修改 / 监听场景有一些现成的库了,从名字上就能看出来用法:document-visibility、network-status、online-status、window-scroll-position、window-size、document-title。组件辅助
Hooks 还可以增强组件能力,比如拿到并监听组件运行时宽高等。
获取组件宽高效果:通过调用 useComponentSize 拿到某个组件 ref 实例的宽高,并且在宽高变化时,rerender 并拿到最新的宽高。
const ref = useRef(null); let componentSize = useComponentSize(ref); return ( <> {componentSize.width}