Hooks核心01

React 本质

就是 Modal 到 View 层的映射,当 Modal 中的状态发生变化时,UI 会自动变化,即所谓的数据绑定

所以,可以把 UI 看成的展现看成是函数的执行过程,当 state 或者 props 发生变化时,react 的函数(组件)会重新执行,生成新的虚拟 dom 并通过 react 以最优的方式更新到浏览器的真实 dom。

映射

Hooks 是什么?

Hooks 就是把某个目标的结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果

对于函数组件来说,这个结果就是最终的 dom 树;对于 useCallback、useMemo 这样与缓存相关的 hooks 组件,则是在依赖项发生变化时去更新缓存。

hook

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)

缺点:

  1. 代码难理解,不直观,很多人甚至宁愿重复代码,也不愿用高阶组件;
  2. 会增加很多额外的组件节点。每一个高阶组件都会多一层节点,这就会给调试带来很大的负担。

hooks 方案

  1. 首先实现一个 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;
};
  1. 使用 hooks
const MyComponent = () => {
  const size = useWindowSize()
  if (size === "small") return <SmallComponent />
  else return <LargeComponent />
}

Hooks 的另一大好处:有助于关注分离

比如上面监听浏览器窗口大小的变化为例,我们来看 Hooks 是如何做到关注分离的?

  • 在过去的 Class 组件中,我们需要在 componentDidMount 中监听事件,在 componentWillUnmount 中去解绑事件。
  • 而在函数组件中,我们可以把所有逻辑写在一起。

为什么函数组合的方式要优于继承?

组合的话组件仅仅需要通过props的方式来相互交互,依赖关系更加清楚,组合的内聚性会更好。
继承会让两个组件紧密的耦合在一起,继承要达到的目标组合都可以cover

Published under  on .

pipihua

我是皮皮花,一个前后端通吃的前端攻城狮,如果感觉不错欢迎点击小心心♥(ˆ◡ˆԅ) star on GitHub!