系统运行到某一时期时,会调用被注册到该时机的回调函数。

比较常见的钩子有:windows 系统的钩子能监听到系统的各种事件,浏览器提供的 onload 或 addEventListener 能注册在浏览器各种时机被调用的方法。

以上这些,都可以被称一声 "hook"。

函数式组件

更好的状态复用

怼的就是你,mixin

class 组件模式下,状态逻辑的复用是一件困难的事情。

假设有如下需求:

当组件实例创建时,需要创建一个 state 属性:name,并随机给此 name 属性附一个初始值。除此之外,还得提供一个 setName 方法。你可以在组件其他地方开销和修改此状态属性。

更重要的是: 这个逻辑要可以复用,在各种业务组件里复用这个逻辑。

在拥有 Hooks 之前,我首先会想到的解决方案一定是 mixin

代码如下:(此示例采用 vue2 mixin 写法 )

// 混入文件:name-mixin.js
export default {
  data() {
    return {
      name: genRandomName() // 假装它能生成随机的名字
    }
  },
  methods: {
    setName(name) {
      this.name = name
    }
  }
}
复制代码
// 组件:my-component.vue
<template>
  <div>{{ name }}</div>
<template>
<script>
import nameMixin from './name-mixin';
export default {
  mixins: [nameMixin],
  // 通过mixins, 你可以直接获得 nameMixin 中所定义的状态、方法、生命周期中的事件等
  mounted() {
    setTimeout(() => {
      this.setName('Tom')
    }, 3000)
  }
}
<script>
export default {
  mixins: [ a, b, c, d, e, f, g ], // 当然,这只是表示它混入了很多能力
  mounted() {
    console.log(this.name)
    // mmp!这个 this.name 来自于谁?我难道要一个个混入看实现?
  }
} 

自定义hooks

import React from 'react';

export const useName = () => {
  // 这个 useMemo 很关键
  const randomName = React.useMemo(() => genRandomName(), []);
  const [ name, setName ] = React.useState(randomName)

  return {
    name,
    setName
  }
}

ts hook

  • 在组件中可以直接使用过import {useStore} from 'vuex' 或者使用import store from '@/store'
/**
 * 
 *  定义 hooks
 */

import { SET_TODO } from "@/store/actionTypes";
import { FINISHIED_STATUS, IItodo } from "@/typings";
import { Store, useStore } from "vuex";

interface UseTodo {

    setTodo: (value: string) => void;
    getTodo: () => void;
    setTodoList: () => void;
    removeTodo: () => void;
    updateTodo: () => void;
}


function useTodo(): UseTodo {

   const store: Store<any> = useStore();
    /**
     * 组装参数
     * 调用 store  dispatch --> action ---> mutation-- > state ---> render
     * @param value 
     */
    function setTodo(value: string): void {

        const todo: IItodo = {
            id: new Date().getTime(),
            content: value,
            status: FINISHIED_STATUS.NO
        }
        //  调用 vuex store 
        // store.dispatch('',todo)
       
        store.dispatch(SET_TODO, todo);
    }

    function getTodo() {

    }

    function setTodoList() {

    }

    function removeTodo() {

    }

    function updateTodo() {

    }

    return {
        setTodo, getTodo, setTodoList, removeTodo, updateTodo
    }
}

export {
    UseTodo
}