React-hooks Design Motivation and Working Mode (PART 1)

Many people aren’t confident in their knowledge of React-hooks, at least in interview Settings. Few people can talk as much about them as they can about Diff Hooks or Fiber. So what’s the problem? It is probably in the method and way of learning.

React-hooks many people think of useState, useEffect, useContext as trivial and numerous apis. There seems to be nothing mystical about react-hooks, so what exactly do interviewers want to hear every time they ask about react-hooks?

1. Learn the correct path to react-hooks

In the previous learning process, we can know that when we learn a new thing from the shallow to the deep, we often need to follow a cognitive process like “Why→What→How”. However, it is not perfect to only learn “What” and “How” well. To further master knowledge, we need to study the “Why” behind it. These three are complementary and indispensable: when we understand the specific “What” and “How”, we can often answer the theoretical “Why” more concretely. And our exploration and cognition of “Why” will inevitably feed back our understanding of “What” and practice of “How”. Therefore, the control of “Why” should not be neglected.

React-hooks have only really been introduced since React 16.8 and are likely new to every React developer. If in the process of cognition, we can follow such a learning rule as “Why→What→How”, and use this as a clue to sort out our own complete knowledge link. So, no matter how difficult the face of the interviewer, can do know, answer.

Follow this learning rule and challenge react-hooks to truly understand the design motivations and working patterns behind them.

React-hooks: Why react-hooks

React-hooks are the react-hooks that the React team gradually realized during the development of the React component. This involves thinking and focusing on both class components and function components. Therefore, we first recognize and differentiate what are class components and function components.

(1) What is Class Component?

The React component is derived from react.componentbased on ES6 Class. Here is a typical class component:

Class DemoClass extends React.Component {// Initializes the state of a class component state = {text: ""}; // Write the lifecycle method didMount componentDidMount() {// omit business logic} // write a custom instance method changeText = (newText) => {// update state this.setState({ text: newText }); }; Return (<div className="demoClass"> <p>{this.state.text}</p> <button OnClick ={this.changeText}> </button> </div>); }}Copy the code

(2) What is Function Component/Stateless Component?

The React component is, as the name suggests, a function. In the early days, react-hooks were not implemented. Function components could not define and maintain state internally, hence the name “stateless component”. Here is a typical function component:

function DemoFunction(props) { const { text } = props return ( <div className="demoFunction"> <p>{`function [${text}] '}</p> </div>); }Copy the code

(3) Comparison between function components and class components: Not “pros and cons”, only “different”

Based on the above two demos, the two components are morphologically distinguished. The visible differences between them include but are not limited to:

  • Class components need to inherit class, function components do not;

  • Class components have access to lifecycle methods, function components do not;

  • Class components can get instantiated this and do all sorts of things based on this, but function components can’t;

  • State can be defined and maintained in class components, but not in function components;

.

From the above points alone, we can see the frequent occurrence of “class components can XXX, function components can not XXX”. Does this mean that class components are better than function components?

The answer, of course, is no. You could say that in a world before react-hooks, class components had significantly stronger capability boundaries than function components, but it would be a stretch to go further and say that class components were stronger than function components. Similarly, some articles blindly advocate function components lightweight elegant start quickly, in the near future will be the class components dry, these statements are biased, and therefore can not be biased.

When discussing these two component forms, we should not hold the prejudice of “which one is better than the other”, but should pay more attention to the differences between them, and then connect different characteristics with different scenes, so as to obtain a comprehensive and dialectical cognition.

3. Reunderstanding class Components: Reloading warships wrapped in object-oriented thinking

Class component is a representation of object-oriented programming. Object orientation is an old concept. When we apply object orientation, we always do two things, intentionally or unintentionally.

  • Encapsulation: “aggregating” a Class of properties and methods into a single Class.

  • Inheritance: A new Class can reuse a Class of properties and methods by inheriting an existing Class.

The React class component is no exception. Take another look at the typical class component Case:

Class DemoClass extends React.Component {// Initializes the state of a class component state = {text: ""}; // Write the lifecycle method didMount componentDidMount() {// omit business logic} // write a custom instance method changeText = (newText) => {// update state this.setState({ text: newText }); }; Return (<div className="demoClass"> <p>{this.state.text}</p> <button OnClick ={this.changeText}> </button> </div>); }}Copy the code

As you can see, the React class component has quite a few “things off the shelf” built-in for you to schedule/customize. State and life cycles are typical examples of these “things off the shelf”. It’s not that hard to get these things, you just have to gently inherit a react.component.

It’s as if you’ve effortlessly acquired a “heavy battleship,” with all the guns and missiles you need, ready for you to operate a bunch of switches on the console.

There’s no doubt that class components offer developers plenty, but is “more” good? Not necessarily.

If you put a man in a heavy battleship, does he have to be able to operate it? If he is not trained and does not know the meaning of each operation point, he will most likely hit a friendly camp.

The React class component has the same problem — you need to learn as much as it provides. If you can’t hold the life cycle, your logical order of components will most likely become a mess. Behind the “big and complete”, there is a learning cost that cannot be ignored.

Consider this scenario: instead of killing an army, it’s just a mosquito. At this time to continue to start the “heavy battleship”, is not “overqualified”? This is one of the inconveniences of class components: writing a class component to solve a small problem is too cumbersome a process. Complex implementations inevitably come with a high cost of understanding, which is not what we expect.

Even worse, the logic written by the developer is stuck to the component after encapsulation, making it difficult to split and reuse the logic inside the class component. If you want to break this deadlock, you need to further learn more complex design patterns (such as higher-order components, Render Props, etc.), with higher learning costs in exchange for some coding flexibility.

All of this is a headache just thinking about it. So while class components are powerful, they are not a panacea.

4. Learn more about Function components: React’s Lightweight speedboat

Let’s look at the example code for this function component:

function DemoFunction(props) { const { text } = props return ( <div className="demoFunction"> <p>{`function [${text}] '}</p> </div>); }Copy the code

Of course, if you think that a function component is simple because it can only handle rendering, you are underestimating it. It can also handle relatively complex interaction logic, as shown in the following code:

Function DemoFunction(props) {const {text} = props const showAlert = ()=> {alert(' ${text} ')} return (<div ClassName ="demoFunction"> <p>{' function ' [${text}] `} < / p > < button onClick = {showAlert} > click popup window < / button > < / div >). }Copy the code

Compared to class components, functional components have obvious features such as lightness, flexibility, ease of organization and maintenance, and lower learning costs. These elements are unquestionably important, and they certainly drove the React team to change. But in addition to this, there is a very easy to be overlooked, and very few people really understand the point of knowledge, I want to focus on here. This comes from an excellent comparison of class components and function components written by React author Dan Early on. It’s a long article, but it’s all about the same thing:

The function component captures the state inside render, which is the biggest difference between the two types of components.

When I first read this article, I was struck by how important the JS closure mechanism was for solving problems. But now, after much reflection, we know that there are many differences between class components and functional components, but the most important one that can’t be overlooked is the mental model difference, the difference between object-oriented and functional programming.

Specifically, it isFunction components more closely match the React framework design philosophy. Why do you say that? Don’t forget the famous React formula:

The React component is literally a function itself, a function that eats data and spit out the UI. As developers, we write declarative code, and the React framework’s main job is to convert declarative code into imperative DOM operations in a timely manner, mapping data-level descriptions to user visible UI changes. This means that, in principle, React data should always be tightly bound to render, whereas class components can’t.

So why can’t class components do that? Here we take the Demo from the above article and stand in a new perspective to interpret the conclusion that “function components capture the state inside render, which is the biggest difference between the two types of components”. Let’s start with a class component like this:

class ProfilePage extends React.Component { showMessage = () => { alert('Followed ' + this.props.user); }; handleClick = () => { setTimeout(this.showMessage, 3000); }; render() { return <button onClick={this.handleClick}>Follow</button>; }}Copy the code

This component returns a button, and the interaction content is very simple: click the button, 3s later, the interface will pop up a copy of “Followed XXX”. This is similar to the “follow someone” reminder that pops up after we click “follow someone” on Weibo.

This may seem fine, but if you try to switch the user to Sophie within three seconds of clicking on the ProfilePage button in the form of a class component in this online Demo, you should see something like this:

We clicked “Followed Sophie” on Dan’s page instead of “Followed Sophie”!

The content of user is delivered via props, while the value of props is immutable. Why is the value of user changed from Dan to Sophie?

While this is immutable, the data on this can be modified. A call to this. Props gets the latest props every time, which is an important way to ensure real-time data in React.

In most cases, with the React lifecycle controlling the order of execution, this. Props and this. State can change in accordance with the expected render action. But in this case, setTimeout delayed the expected rendering by 3s, breaking the timing association between this.props and the render action, resulting in an incorrect, modified version of this.props being captured during rendering. That’s the problem.

But if you modify the ProfilePage to a function component that looks like this:

function ProfilePage(props) {
  const showMessage = () => {
    alert('Followed ' + props.user);
  };
  const handleClick = () => {
    setTimeout(showMessage, 3000);
  };
  return (
    <button onClick={handleClick}>Follow</button>
  );
}
Copy the code

Things would have been very different:

The props are captured at the moment the ProfilePage function executes, and since the props themselves are immutable, it is sufficient to ensure that at any time from now on, the props read is the one that was originally captured. When the parent component passes in a new props to try to re-render the ProfilePage, it is essentially issuing a new function call based on the new props input, without affecting the previous call’s capture of the previous props. This ensures that the render results are actually as expected.

At this point, not only do you fully understand Dan’s statement that the function component captures the state inside render, but you can take a step further and realize that the function component actually binds data to render.

Over the years, the React team has clearly realized that function components are a better representation of components that match its design philosophy and are better suited for logical separation and reuse. The React team then started supporting developers in writing functional components, resulting in react-hooks.

The essence of Hooks: A set of Hooks that make functional components more powerful and flexible

What are react-hooks? It is a set of “hooks” that make functional components more powerful and flexible.

As mentioned earlier, functional components have a lot less than class components, such as life cycles, management of state, and so on. This brings many limitations to the use of functional components, and makes it impossible to write a truly functional component in the form of a function.

React-hooks are used to help function components fill in these missing capabilities (as opposed to class components).

If a function component is a lightweight speedboat, react-hooks are a rich box of parts. “Reshipment battleship” preset by the equipment, the basic all have the box, all at the same time it also don’t force you to, but allows you the freedom to choose and use the ability you need, and then the ability to Hook (Hook) in the form of a “Hook” into your component, to customize an “exclusive” battleship is best for you.

6, summary

So far, the research on “Why” has been basically in place, and the cognition of “What” has begun to take shape. React-hooks although there is not a single line of react-hooks code in this tutorial, I believe that many react-hooks developers already know more about the nature of react-hooks than they do.

Next, face to face with react-hooks, learning “What” in code and “How” in practice. I believe that in the end, I will have a deeper understanding and comprehension of the “Why” explained in this paper.

Learning the source (the article reprinted from) : kaiwu.lagou.com/course/cour…