📖 Read this article and you will:

  1. Learn about Hooks in Vue and React

  2. Listen to the author’s definition and summary of Hooks

  3. Understand “Why do we need Hooks”

  4. Do some simple Hooks practices

What is the general trend?

In early 2019 react officially got hooks in version 16.8.x.

In June 2019, You Yuxi presented a vue3 Component API proposal in Vue/Github-Issues. (Base on vue hooks)

In subsequent versions of React and VUe3, the hooks ability began to gain more acceptance.

In addition, frameworks like Solid. Js and Preact are starting to join the hooks family.

For now, class Component and hooks apis are running hand-in-hand, but hooks are likely to replace Class Component as the true mainstream in the next few years.

Two, what ishooks?

You didn’t understand me when I was young, just as I didn’t understand hooks😭.

2.1 hooksThe definition of

Literally, “hooks, “which aren’t just a term for React, or even for the front-end world, but for the entire industry. Usually refers to:

When the system runs to a certain period, it invokes the callback function registered for that period.

Common hooks are: Windows hooks that listen to system events, and browser-provided onload or addEventListener that register methods that are called at various times in the browser.

All of these can be called “hooks”.

But it is clear that the word hooks have been given some special meaning on a particular topic in a particular area.

Before [email protected], when we talked about hooks, we were probably talking about “component lifecycle”.

But now hooks take on a whole new meaning.

Use react as an example. Hooks are:

A series of methods that begin with “use” provide the ability to do almost all of your component development — lifecycle, state management, logic reuse — in functional components, bypassed class writing altogether.

To simplify:

A series of methods that provide the ability to do development work in functional components.

(Remember the key word: functional components)

import { useState, useEffect, useCallback } from 'react';
// The above methods are typical of which are Hooks
Copy the code

In Vue, hooks are vaguely defined, so to summarize:

The VUE composite API, which begins with “use,” provides a set of methods for component reuse, state management, and other development capabilities.

(Key words: Combined API)

import { useSlots, useAttrs } from 'vue';
import { useRouter } from 'vue-router';
// These methods are also related hooks in VUe3.
Copy the code

For example: useSlots, useAttrs, useRouter, etc.

But subjectively, I think the vUE composite API itself is a key part of the “Vue hooks” that are at the heart of life cycle and state management in React hooks. (such as onMounted, ref, and so on).

By that standard, vue and React hooks seem to have the same definitions.

So why mention methods that start with “use”?

2.2 Naming conventions and guidelines

Generally, hooks are named after use, and this specification includes custom hooks as well.

Why is that?

Because of (love mistake) appointment.

In the React documentation, hooks are defined and used using the “one if, two only” core guidelines. (Broadcast voice)

One hypothesis: Assume that any function that begins with “use” followed by a capital letter is a Hook.

The first is only: call a Hook in the React function component, not in normal functions. (Eslint determines whether a method is a React function by determining if it is named after a big blob)

The second is only: use hooks only at the top level, and do not call hooks in loops, conditions, or nested functions.

Naming useXxx is not mandatory because it is a convention. You can still name your custom hooks byXxx or some other way, but it is not recommended.

Because the power of conventions is that we can learn what a convention is by naming it without looking at the implementation.

React: One if, two only

  1. Zh-hans.reactjs.org/docs/hooks-…
  2. Zh-hans.reactjs.org/docs/hooks-…

Why do we need ithooks ?

3.1 Better state reuse

It’s you, Mixin!

Reuse of state logic is difficult in class component mode.

Assume the following requirements:

When a component instance is created, you need to create a state property: name and attach a random initial value to the name property. In addition, you must provide a setName method. You can overhead and modify this state property elsewhere in the component.

More importantly, the logic needs to be reusable, across a variety of business components.

Before Hooks, the first solution I would have thought of was mixin.

The code is as follows :(this example is written using vue2 mixin)

// mixin the file: name-mixin.js
export default {
  data() {
    return {
      name: genRandomName() // Pretend it generates random names}},methods: {
    setName(name) {
      this.name = name
    }
  }
}
Copy the code
// Component: my-component.vue
<template>
  <div>{{ name }}</div>
<template>
<script>
import nameMixin from './name-mixin';
export default {
  mixins: [nameMixin],
  // With mixins, you can directly obtain states, methods, life cycle events, and so on defined in nameMixin
  mounted() {
    setTimeout(() = > {
      this.setName('Tom')},3000)
  }
}
<script>
Copy the code

At first glance, mixins seem to offer excellent reuse capabilities, but the React documentation is straightforward:

Why is that?

Mixins offer this ability to reuse state, but they have too many disadvantages.

Drawback 1: difficult to trace the method and attribute!

Imagine if you would doubt life if such code appeared:

export default {
  mixins: [ a, b, c, d, e, f, g ], Of course, that just means it has a lot of power mixed in
  mounted() {
    console.log(this.name)
    // mmp! Who does this. Name come from? Am I supposed to sneak in one by one?}}Copy the code

Or:

a.js mixins: [b.js]

b.js mixins: [c.js]

c.js mixins: [d.js]

// Can you guess who this.name comes from?
// Please stop talking, my blood pressure is up
Copy the code

Disadvantages two: coverage, the same name? What a mess in your circle!

When I tried to mixin both mixin-a.js and mixin-b.js to gain both their powers, something unfortunate happened:

Since the developers of both mixin functions are sympathetic, they both define this.name as an attribute.

At such times, you seriously wonder if mixins are a scientific way to reuse.

Malpractice three: mei open two degrees? The price is high!

Again, if my requirements change, INSTEAD of a simple state name, I need firstName and lastName, respectively. The ability to mix name-mixin.js becomes awkward because I can’t mixins the same file twice.

Of course, there are solutions, such as:

// Generate mixins dynamically
function genNameMixin(key, funcKey) {
  return {
    data() {
      return {
        [key]: genRandomName()
      }
    },
    methods: {
      [funcKey]: function(v) {
        this.[key] = v
      } 
    }
  }
}

export default {
  mixins: [
    genNameMixin('firstName'.'setFirstName'),
    genNameMixin('lastName'.'setLastName')]}Copy the code

It is true that the reuse of capabilities is accomplished by dynamically generating mixins, but this undoubtedly increases the complexity of the program and reduces readability.

So a new kind of “state logic reuse” is desperately needed: Hooks!

Hook state reuse writing method:


// A single name
const { name, setName } = useName();

// Open the second degree
const { name as firstName, setName as setFirstName } = useName();

const { name as secondName, setName as setSecondName } = useName();

Copy the code

Compared to mixins, they’re awesome!

  1. Are methods and properties traceable? This is great. It’s easy to see who made it and where it came from.
  2. Will there be duplication, coverage issues? Not at all! The internal variables are inside the closure, and the returned variables are supportedasAlias.
  3. Multiple times, no N degrees? You look at the above code block is not “mei opened three degrees”?

Hooks are already making my mouth water on the grounds of state logic reuse.

3.2 Code Organization

Entropy reduction, cosmology to coding philosophy.

Projects, modules, pages, functions, how to organize code efficiently and cleanly is a deceptively simple proposition that books can’t fully explain.

But having code for N things entangled within a component on a page was a very common state of affairs before Hooks came along.

So what improvements do Hooks bring to code organization?

(Assume that each color in the figure represents a highly correlated business logic.)

This is done in both Vue and React using Hooks, which are used to write “chunks of code scattered in various declaration cycles” that are linked together by Hooks.

The benefits are obvious: “High convergence, improved readability.” The result is “more efficient, less buggy.”

According to the theory of “physics”, this way of organizing code is “entropy reduction”.

3.3classComponents are easier to understand

Especially this.

Bind (this) can be seen everywhere in the react class notation. (Even the official documentation has a section on “Why binding is Necessary?” The problem)

Don’t laugh vUE players, computed: {a: () => {this}} is also undefined.

Clearly, binding, while “necessary,” is not an “advantage,” but rather a “failure prone” location.

In which Hooks are used, you don’t have to worry about this at all.

Because:

Originally nothing, where to provoke dust.

Which is a direct goodbye to this, from “functions” to “functions”.

Mom doesn’t have to worry about me forgetting to write bind anymore.

3.4 Friendly incremental

The wind into the night, moisten things silently.

Progressive means you can use it little by little.

Both Vue and React simply provide the Hooks API and put their pros and cons there. There is no unacceptable break change forcing you to use Hooks to rewrite previous class components.

You can still write the Hooks component as well as the Class component on your project, a painless thing that quietly changes everything as the project evolves and develops.

But the trend is clear. More and more people are joining the Hooks and composite apis.

How to start playinghooks

4.1 Environment and Version

In the React project, the React version needs to be higher than 16.8.0.

In vue projects, vue3.x is the best choice, but vue2.6+ with @vue/ composition-API can also start to enjoy the joy of “composite API”.

4.2 the reactHookswriting

Because React Hooks only support “functional” components, you need to create a functional component my-component.js.

// my-component.js
import { useState, useEffect } from 'React'

export default() = > {UseState allows you to create a state attribute and an assignment method
  const [ name, setName ] = useState(' ')

  // Side effects can be handled with useEffect
  useEffect(() = > {
    console.log(name)
  }, [ name ])

  // useMemo generates a message variable dependent on name
  const message = useMemo(() = > {
    return `hello, my name is ${name}`
  }, [name])

  return <div>{ message }</div>
}
Copy the code

Details refer to the react’s official website: react.docschina.org/docs/hooks-…

4.3 the vueHookswriting

Vue Hooks rely on the combinatorial API, so this example is written using

<template>
  <div>
    {{ message }}
  </div>
</template>
<script setup>
import { computed, ref } from 'vue'
// defines a ref object
const name = ref(' ')
// defines a calculated property that depends on name.value
const message = computed(() = > {
  return `hello, my name is ${name.value}`
})
</script>
Copy the code

Obviously, the VUE composite API that does useState and useMemo work is not named after useXxx, but follows vue’s descendants ref and computed.

React Hook does not comply with the React Hook convention, but it is not a problem that the Vue API does not comply with the React Hook convention.

Reference site: v3.cn.vuejs.org/api/composi…

5. Start your first customizationhook

In addition to the official Hooks Api, another important feature of Hooks is that they can define their own “custom Hooks” for reuse of state logic.

The open source community also has a lot of good Hooks based packages like ahooks (ahooks.js.org/zh-CN/), vueuse (vueuse.org/)

Vueuse: I’m not allowed to be a Vuer, your toolset is loDash! .

So how do we start writing “custom Hooks”? Read on!

5.1 React Players can see it here at 👈

The React official website has a section devoted to “custom hooks.” (react.docschina.org/docs/hooks-…).

Here, we use the useName requirement at the beginning of the article as an example to achieve this effect:

const { name, setName } = useName();
// Randomly generate a state attribute named, which has a random name as an initial value
// It also provides a method setName that can update the value at any time
Copy the code

If we want to do this, how do we write the code?

import React from 'react';

export const useName = () = > {
  // This useMemo is critical
  const randomName = React.useMemo(() = > genRandomName(), []);
  const [ name, setName ] = React.useState(randomName)

  return {
    name,
    setName
  }
}
Copy the code

Again, it’s tempting to say that mixins are not only better to use, but also easier to define.

Some of you may wonder why you don’t just write:

const [ name, setName ] = React.useState(genRandomName())
Copy the code

Because this is not written correctly, the genRandom() method is executed every time a function component using this Hook is rendered, which does not affect the value of name, but incurs performance costs and even other bugs.

IO /s/long-cher… codesandbox.io/s/long-cher…

5.2 VUE players go to 👈

There is no gameplay description of custom hooks on the vue3 website, but it is not difficult to practice.

The target is also to implement a useName method:

import { ref } from 'vue';

export const useName = () = > {
  const name = ref(genRandomName())
  const setName = (v) = > {
    name.value = v
  }
  return {
    name,
    setName
  }
}
Copy the code

5.3 vuereactThe customHookThe similarities and differences

  • Similarity: The general idea is the same and follows the core idea of “define state data”, “manipulate state data”, and “hide details”.

  • In Vue3, setup exists as an earlier “created” lifecycle, however, and is only introduced once in a component’s rendering process. React function components are completely different. If they are not memorized, they may be triggered over and over again, entering and executing methods, and therefore require more overhead than vUE.

Sixth, concluding remarks

I’m Spring brother. Older front end workers are still studying hard. My goal is to share with you the most practical, the most useful knowledge point, I hope you can come off work early, and can quickly complete the work, calm touch fish 🐟.

You can pay attention to me in nuggets: spring elder brother’s dream is to touch fish, can also find me in the public number: the front end to touch fish.