Think back to the process of getting into Hooks, did you:

  1. Learn when to execute Hooks by analogy to the ClassComponent lifecycle

  2. As you get better at it, you realize that Hooks have different timing and lifecycle times. Such as componentWillReceiveProps corresponding which Hooks?

  3. Confused, read something on Hooks principles

As an API, shouldn’t it be simple and cute to call from a document? Why are Hooks so hard?

React rewrites the document based on Hooks. Rewrites the document based on Hooks.

This paper mainly includes two aspects:

  1. Explain why Hooks are difficult to learn

  2. Give advice on learning Hooks

React’s underlying architecture

React can be summarized in one formula:

const UI = fn(state);
Copy the code

Views can be thought of as states being mapped by functions.

The interaction between the user and the interface can be seen as the continuous implementation of this formula.

This formula is too simplistic to explain where state comes from. Let’s expand:

const state = reconcile(update);
const UI = fn(state);
Copy the code
  1. User interaction generates updates

  2. Update calculates the state of the current application through the Reconcile step

  3. Fn maps state to view changes (UI)

Let’s call fn commit:

const state = reconcile(update);
const UI = commit(state);
Copy the code

So where does the update happen? Of course it comes from user interactions, such as click events.

The React infrastructure can be simplified into three steps:

  • User interaction generates updates

  • state = reconcile(update);

  • UI = commit(state);

Now that we know the underlying architecture, let’s look at the problem of learning Hooks by analogy with ClassComponent.

The abstraction level of a lifecycle function

Now that we have a complete infrastructure to drive view updates, how do developers navigate this architecture?

Consider the computer’s level of abstraction:

Top layer: application middle layer: operating system bottom layer: Computer component architectureCopy the code

Corresponding to the React:

High level: application ClassComponent Lifecycle Middle level: API for operating system intervention architecture Low level: Computer component architecture React low level architectureCopy the code

As you can see, lifecycle functions are at a higher level of abstraction. It was also designed to make React easier for developers to learn.

Imagine a Vue2 developer moving to the React stack and learning the React lifecycle by analogy with the Vue lifecycle.

All this was fine until Hooks arrived, however……

The abstraction level of Hooks

Hooks belong to a medium level of abstraction. That is, Hooks are directly involved in the running process of the underlying architecture.

High level: application Hooks Middle level: OPERATING system Hooks Low level: Computer architecture React Low level architectureCopy the code

When we use lifecycle functions as an analogy to Hooks, we are using things at a high level of abstraction to describe things at a low level of abstraction.

Animals –> mammals –> cows –> cows

How do you explain mammals to someone who has only seen cows and no other animals?

It is this asymmetry in the level of abstraction that causes the problem of learning Hooks through the lifecycle function analogy.

How to learn Hooks

Since Hooks are at the middle level of abstraction, close to the bottom, it is better to learn from the bottom and up.

Here’s our three-step formula:

  • User interaction generates updates

  • state = reconcile(update);

  • UI = commit(state);

By comparison with the formula, let’s explain the working process of several common hooks:

useState

Here’s an example:

function App() {
  const [state, updateState] = useState(0);
  return <div onClick={()= > updateState(state + 1)}></div>;
}
Copy the code

The useState return value array contains:

  1. Save the state of

  2. Change the state method updateState

According to the formula, state belongs to the formula calculated in Step 2:

  • state = reconcile(update);

The view has not been updated at this point.

The user clicks div to trigger updateState, which corresponds to step 1:

  • User interaction generationupdate

So calling updateState starts the three-step running process of the underlying architecture.

When Reconcile computes state, the third step is taken:

  • UI = commit(state);

Final render view.

useEffect

Here’s an example:

useEffect(doSomething, [xx, yy])
Copy the code

UseEffect’s callback function doSomething is called asynchronously after the third step:

  • UI = commit(state);

So inside the doSomething function you can get the view where the update was done.

The second argument [xx, YY], as a dependency, determines whether doSomething will be called.

useLayoutEffect

Unlike useEffect, which is called asynchronously after step 3, useLayoutEffect is executed synchronously after step 3.

useRef

As can be seen from the above examples, useState and useEffect are triggered in different steps of the three-step process respectively, and their trigger timing is determined.

So how do these three steps communicate? Through useRef.

UseState applies to the first and second steps, useLayoutEffect applies to the third step, and useEffect applies to the third step after completion.

With useRef, you can share reference type data between steps.

As you can see, React provides hooks for each step of the three-step workflow of the underlying architecture, as well as hooks that connect the three steps together.

The developer simply assembles custom Hooks based on business needs, using base Hooks, to run logic at various times in the underlying architecture running the process.

Is bottom-up learning putting the cart before the horse?

Learn React. Learn how to execute lifecycle functions. Now learn Hooks. Isn’t the cart before the horse more complicated?

It’s not. Let me ask you a few questions:

  1. Why componentWillReceiveProps is marked as unsafe?

  2. GetDerivedStateFromProps used before?

  3. Is this.setState synchronous or asynchronous?

These life cycle function related questions are not easy at all! Many React front ends that have been used for years don’t always answer.

As a high-level abstraction, lifecycle functions hide too many implementation details. React was also too flexible, unlike Vue, which restricted what developers could do with a template language.

The result: Different React developers write all sorts of weird ClassComponents.

Instead, run the process through the underlying architecture

  • The underlying architecture running flow is the absolute truth of React. There are no abstractions to hide

  • The Hooks writing specification limits developers from doing weird things

The only problem here is the lack of documentation from the bottom up. This is why React rewrites the document.

For developers who are familiar with React, learn about the React Technology before the official new documentation is released.

Here are some other perspectives from which to talk about Hooks:

  • From the conceptual level: Algebraic effects and Hooks

  • At the micro (code) level: source code implementation for all common Hooks