Hooks核心01
React 本质
就是 Modal 到 View 层的映射,当 Modal 中的状态发生变化时,UI 会自动变化,即所谓的数据绑定
所以,可以把 UI 看成的展现看成是函数的执行过程,当 state 或者 props 发生变化时,react 的函数(组件)会重新执行,生成新的虚拟 dom 并通过 react 以最优的方式更新到浏览器的真实 dom。
Hooks 是什么?
Hooks 就是把某个目标的结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果
对于函数组件来说,这个结果就是最终的 dom 树;对于 useCallback、useMemo 这样与缓存相关的 hooks 组件,则是在依赖项发生变化时去更新缓存。
Hooks 带来最大的好处:简化逻辑复用
场景:根据不用的屏幕大小适配不同的组件
class 的高阶组件方案:
const withWindowSize = Component => {
// 产生一个高阶组件 WrappedComponent,只包含监听窗口大小的逻辑
class WrappedComponent extends React.PureComponent {
state = {
size: this.getSize()
};
componentDidMount() {
window.addEventListener("resize", this.handleResize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.handleResize);
}
getSize() {
return window.innerWidth > 1000 ? "large" :"small";
}
handleResize = ()=> {
const currentSize = this.getSize();
this.setState({
size: this.getSize()
});
}
render() {
// 将窗口大小传递给真正的业务逻辑组件
return <Component size={this.state.size} />;
}
}
return WrappedComponent;
};
class MyComponent extends React.Component {
render() {
const { size } = this.props
if (size === "small") return <SmallComponent />
else return <LargeComponent />
}
}
// 使用 withWindowSize 产生高阶组件,用于产生 size 属性传递给真正的业务组件
export default withWindowSize(MyComponent)
缺点:
- 代码难理解,不直观,很多人甚至宁愿重复代码,也不愿用高阶组件;
- 会增加很多额外的组件节点。每一个高阶组件都会多一层节点,这就会给调试带来很大的负担。
hooks 方案
- 首先实现一个 hooks
const getSize = () => {
return window.innerWidth > 1000 ? "large" :"small";
}
const useWindowSize = () => {
const [size, setSize] = useState(getSize());
useEffect(() => {
const handler = () => {
setSize(getSize())
};
window.addEventListener('resize', handler);
return () => {
window.removeEventListener('resize', handler);
};
}, []);
return size;
};
- 使用 hooks
const MyComponent = () => {
const size = useWindowSize()
if (size === "small") return <SmallComponent />
else return <LargeComponent />
}
Hooks 的另一大好处:有助于关注分离
比如上面监听浏览器窗口大小的变化为例,我们来看 Hooks 是如何做到关注分离的?
- 在过去的 Class 组件中,我们需要在 componentDidMount 中监听事件,在 componentWillUnmount 中去解绑事件。
- 而在函数组件中,我们可以把所有逻辑写在一起。
为什么函数组合的方式要优于继承?
组合的话组件仅仅需要通过props的方式来相互交互,依赖关系更加清楚,组合的内聚性会更好。
继承会让两个组件紧密的耦合在一起,继承要达到的目标组合都可以cover