代码复用的解决方案层出不穷,但是整体来说代码复用还是很复杂的,这其中很大一部分原因在于细粒度代码复用不应该与组件复用捆绑在一起,HOC、Render Props 等基于组件组合的方案,相当于先把要复用的逻辑包装成组件,再利用组件复用机制实现逻辑复用,自然就受限于组件复用,因而出现扩展能力受限、Ref 隔断、Wrapper Hell等问题,那么我们就需要有一种简单直接的代码复用方式,函数,将可复用逻辑抽离成函数应该是最直接、成本最低的代码复用方式,但对于状态逻辑,仍然需要通过一些抽象模式(如Observable)才能实现复用,这正是Hooks的思路,将函数作为最小的代码复用单元,同时内置一些模式以简化状态逻辑的复用。比起上面提到的其它方案,Hooks让组件内逻辑复用不再与组件复用捆绑在一起,是真正在从下层去尝试解决(组件间)细粒度逻辑的复用问题此外,这种声明式逻辑复用方案将组件间的显式数据流与组合思想进一步延伸到了组件内。
档案Hooks也并非完美,只是就目前而言,其缺点如下:
额外的学习成本,主要在于Functional Component与Class Component之间的比较上。
写法上有限制(不能出现在条件、循环中),并且写法限制增加了重构成本。
破坏了PureComponent、React.memo浅比较的性能优化效果,为了取最新的props和state,每次render()都要重新创建事件处函数。
在闭包场景可能会引用到旧的state、props值。
内部实现上不直观,依赖一份可变的全局状态,不再那么pure。
React.memo并不能完全替代shouldComponentUpdate(因为拿不到state change,只针对props change)。
useState API设计上不太完美。
示例 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>React</title> </head> <body> <div></div> </body> <script src="http://unpkg.com/react@17/umd/react.development.js"></script> <script src="http://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="http://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const {useState, useEffect} = React; function useMouseLocation(location){ return ( <> <h1>请在此处移动鼠标</h1> <p>当前鼠标的位置是: x:{location.x} y:{location.y}</p> </> ); } function MouseTracker(props){ const [x, setX] = useState(0); const [y, setY] = useState(0); function handleMouseMove(event){ setX(event.clientX); setY(event.clientY); } return ( <div onMouseMove={handleMouseMove}> {useMouseLocation({x, y})} </div> ) } ReactDOM.render( <MouseTracker/>, document.getElementById("root") ); </script> </html> 每日一题 https://github.com/WindrunnerMax/EveryDay 参考 https://zhuanlan.zhihu.com/p/38136388 https://juejin.cn/post/6844903910470057997 https://juejin.cn/post/6844903850038525959 https://my.oschina.net/u/4663041/blog/4588963 https://zh-hans.reactjs.org/docs/hooks-intro.html https://zh-hans.reactjs.org/docs/hooks-effect.html https://react-cn.github.io/react/docs/reusable-components.html %E7%BB%84%E4%BB%B6%E9%97%B4%E9%80%BB%E8%BE%91%E5%A4%8D%E7%94%A8/