How React Hooks Work

How React Hooks Work

1. React Hooks vs. Pure Functions

To put it simply, React Hook is some new APIs added in React V18.6. The essence of API is to provide a function interface for certain functions. Therefore, React Hooks are functions, but React Hooks are not pure functions.

What is a pure function? That is, this function must produce the same output when the input value is the same, and this function cannot affect external data.
Simply put, variables defined outside cannot be used inside a function, because if variables defined outside are used, when the external variables change, it will affect the calculation inside the function, and the function will also affect the external variables.

The functional API provided by React Hooks is not a pure function.
Let’s look at a useState statement const [count, setCount] = useState(0). The results of using the useState function are not always the same, because if the result of useState(0) is the same every time, then the count value will never change, and the page where the count is located will never change, which is different from the result we see. From this we can see that React Hooks are not pure functions, which means that Hooks use variables outside of functions.

So what is it that makes React Hooks not pure functions? In fact, it is determined by the React framework and the function component itself. We know that the principle of React page rendering is to get a new virtual DOM each time you render, and then perform DOM Diff to render the page. React's functional component gets a virtual DOM by executing the entire function. Therefore, every time the page is rendered, all statements inside the function component will be re-executed. If the React Hooks used inside the functional component are pure functions, you will not get a different virtual DOM after each rendering.

React stipulates that all React components must be pure functions and are prohibited from modifying their own props.

Therefore, before React V16.8, when React Hooks were not yet released, function components, because they were pure functions, could only return a fixed virtual DOM, could not contain states, and did not support lifecycle methods. Therefore, at that time, only function components were supported. However, function components had too many restrictions compared to class components. Function components could not replace class components, nor were they as easy to use as class components.

React wants components to be simple rather than complex. React believes that the best way to write components should be functions rather than classes. Therefore, React added React Hooks. Hook means hook, which is provided by React to function components to "hook" external functions and data status when they are needed, thereby improving function components and enabling them to completely replace class components.

React's function components can only be pure functions, so the task of getting a different virtual DOM when re-rendering the function components every time an event occurs is completely left to React Hooks. So how does React Hooks do it? Next, we will manually implement a useState. The specific details of useState are definitely different, but the principles and ideas are the same.

2. Simple myUseState

The first execution of React.useState assigns the initial value to a _state, and each subsequent re-render reads the value of _state. What setState in [state, setState] does is to change the value of _state and then re-render the page.
According to this principle, the myUseState function is implemented as follows:

import React from 'react';
import ReactDOM from 'react-dom';

let _state

function myUseState(initialValue){
  if(_state === undefined){
    _state = initialValue
  }
  const setState = (newValue)=>{
    _state = newValue
    render()
  }
  return [_state, setState]
}

function render(){
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

3. Improve myUseState

The myUseState implemented above has a bug. When myUseState is used twice in a function component, a problem will occur. The two will share the same _state, which will cause confusion.
Therefore, the above implementation needs to be improved. The idea of ​​improvement is to define _state as a data or object. Since we only pass a numerical value when using the function, we cannot determine the key value, so we can only use the data. The improvements are as follows:

import React from 'react';
import ReactDOM from 'react-dom';

let _state = []
let index = 0

function myUseState(initialValue){
  const currentIndex = index
  if(_state[currentIndex] === undefined){
    _state[currentIndex] = initialValue
  }
  const setState = (newValue)=>{
    _state[currentIndex] = newValue
    render()
  }
  index++
  return [_state[currentIndex], setState]
}

function render(){
  index = 0
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  const [m, setM] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
      <br/>
      m: {m}
      <button onClick={() => setM(m+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

4. Hooks rules triggered by implementation principles

The myUseState implemented above is definitely not the specific implementation code of React.useState, but the implementation principle is the same. The myUseState function encapsulates the data state within the function component and manages the state, exposing the relevant operation interface for the function component to use.
In this way, the function component is separated from its data state. The function component is only responsible for returning the virtual DOM itself, and the management of the data state is completely handed over to the React.useState Hook to which it is "hooked".

From the above implementation ideas, we can find that the implementation of React Hooks is actually a special function based on global variables and closure principles.

However, it is precisely because of this implementation method that the use of React Hooks is limited to calling Hooks only at the top level, which means that Hooks should not be called in loops, conditions, or nested functions. If Hooks are used in if conditional statements, the number of executions of the React.useState statement will be incorrect each time the component is rendered, which will disrupt the index count and cause data maintenance errors.

The above implementation principle relies on the correct counting of indexes, so React relies on the order in which Hooks are called.

The above is a detailed explanation of how React Hooks work. For more information about React Hooks, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of how to pass values ​​between react hooks components (using ts)
  • ReactHooks batch update state and get route parameters example analysis
  • React Hooks Detailed Explanation
  • Common pitfalls of using React Hooks
  • 30 minutes to give you a comprehensive understanding of React Hooks
  • Common usage of hook in react
  • Introduction to 10 Hooks in React

<<:  Using MySQL database with Python 3.4 under Windows 7

>>:  Django uses pillow to simply set up verification code function (python)

Recommend

WeChat applet implements countdown for sending SMS verification code

This article shares the specific code for the WeC...

Implementation of tomcat deployment project and integration with IDEA

Table of contents 3 ways to deploy projects with ...

Pure CSS header fixed implementation code

There are two main reasons why it is difficult to...

JavaScript to achieve a simple countdown effect

This article example shares the specific code of ...

Detailed explanation of the process of zabbix monitoring sqlserver

Let's take a look at zabbix monitoring sqlser...

Play mp3 or flash player code on the web page

Copy code The code is as follows: <object id=&...

Three notification bar scrolling effects implemented with pure CSS

Preface The notification bar component is a relat...

JS implements multiple tab switching carousel

Carousel animation can improve the appearance and...

Detailed explanation of redundant and duplicate indexes in MySQL

MySQL allows you to create multiple indexes on th...

Learn Vue middleware pipeline in one article

Often when building a SPA, you will need to prote...

Detailed explanation of MySQL InnoDB index extension

Index extension: InnoDB automatically extends eac...

CSS to achieve the image hovering mouse folding effect

CSS to achieve the image hovering mouse folding e...

Using jQuery to implement the carousel effect

This article shares the specific code for impleme...