Hook引起对函数式组件的思考

3,766 阅读4分钟

React Hooks在react v16.8版本横空出世后,带来了新的react编程思想,当你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼时,当你搞不清使用哪个生命周期钩子函数时,当你还在为组件中的this指向而晕头转向时,拥抱Hooks,一切问题都会迎刃而解, 让我们来看一眼Hooks最初的样子:

import React, { useState } from 'react';

function Example() {
  // 声明一个新的叫做 “count” 的 state 变量
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

没有setState异步刷新render,只需要通过解构拿到你的值(get)和响应(set),一切看起来都是那么的优雅,下面我们来具体看下Hooks的这种思想如何引起我们对函数式组件的思考。

自定义Hook

通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。

当业务场景下,不会像get和set这么简单,有很多结合Hook使用的地方都需要套用逻辑,比如:

import React, { useState } from "react";

export const testDemo = () => {  
  const [ visible, setVisible ] = useState();

  const openModal = () => {
    setVisible(true);
  }
  const hideModal = () => {
    setVisible(false);
  }
  return (    
    <React.Fragment>      
      <div onClick={openModal}>open Modal!</div>      
      <Modal visible={visible} onCancel={hideModal} />    
    </React.Fragment>  
  );
};


可以发现除了 visible 这个必要的变量外,想要控制modal就必须要有open和close的方法调用,其实如果只是写一个组件看起来代码量还好,但每使用一个Modal,就比定会有一套相同的逻辑需要重写,这势必会增加代码冗余。

那么如果想要解决此类问题,就需要封装逻辑,我们这里使用自定义的Hook useModalVisible。话不多说,我们来看一下封装后的代码:


import React, { useState } from "react";
import {useModalVisible} from '@/utils';
export const testDemo = () => {  
    const { visible, hideModal, openModal } = useModalVisible();
    return (    
      <React.Fragment>      
        <div onClick={openModal}>open Modal!</div>      
        <Modal visible={visible} onCancel={hideModal} />    
      </React.Fragment>  
    );
};


可以看到

useModalVisible
是我们自定义的一个Hook,它返回了我们所需要的visible,hideModal,openModal,一次封装,所有Modal受用。

我们来看下自定义的Hook内部实现:

这样就完成了一个自定义的Hook。

目前看到了一个比较有意思的库,根据场景利用Hooks造了很多轮子《react-hanger


函数式组件

我们发现如果复用逻辑可以通过封装Hooks函数来造轮子,如果用来写组件是否可以呢?

答案是必须的。

我们先来看一个实际业务下函数式组件的代码:

可以看到我们的组件接收props,组件通过对象包裹的dom对应的value值返回,还可以将组件产生的一些数据和dom打包成对象一同返回。

调用函数式组件:


这样我们完成了一个函数式组件封装,我们看一下最后我们封装的组件长什么样子:



可以看到当我选择了排序方式或者勾选选择框时,组件内部会产生逻辑和数据,通过retrun我们可以像Hooks一样直接告诉父类我们通过逻辑产生了什么数据,再也不需要像类组件一样callback传来传去,是不是方便很多呢?

结尾

不知道你阅读完整篇文章的感受如何,或者对hooks有任何角度的看法和思考都欢迎在评论区一起讨论。个人感觉Hooks带来的不仅仅是代码上的优雅,还是一种对代码的思考方式。如果文章中有错误或者排版问题请大佬轻喷😂,小老弟这是第一次写文章,希望从代码的索取者变为代码贡献者。最后借用大佬的一句名言:

外在转变过程指的是,建立起一个有潜力或有能力的好名声,这能够在很大程度上改变我们的自我认知; 而内在转变过程涉及内在动机和自我定位的转变,这种转变并不是独立发生的,而是在与他人所建立的关系中渐渐发生的转变。” ——《能力陷阱》