preface

The most important thing about React is components. Before React 16.8 (not Hooks yet), we wrote most of our applications as Class components, because Class components have a lifecycle and control state. But functional components can only stand back and say they are puppet components (also known as stateless components), calling props and presenting the UI

The following text is based on Hooks

The body of the

Are there any fundamental differences between functional components and class components?

Functional components capture values at render time

See this article: How is a functional component different from a class component?

Because React props are immutable, they never change. However, this is mutable

In fact, that’s what the class component this is for. React itself changes over time so that you can get the latest instances in the render method as well as in the lifecycle method

A functional component captures the value in its current state. If you use a timer to change the state of the current value, the functional component displays the original value, not the latest value. The class component always gets the latest value

The functional component captures the current value as soon as it is rendered. The class component is rendered, but its this points to the latest instance

Class components

You can see the online Demo

class ClassDemo extends React.Component { state = { value: "" }; ShowMessage = () => {alert(" latest value is "+ this.state.value); }; handleMessageChange = (e) => { this.setState({ value: e.target.value }); }; handleClick = () => { setTimeout(this.showMessage, 3000); }; render() { return ( <div> <input value={this.state.value} onChange={this.handleMessageChange} /> <button OnClick ={this.handleClick}> click </button> </div>); }}Copy the code

The result is a click to get the most recent value, not the value three seconds ago. Why is that? Since this is mutable, alert(” last value is “+ this.state.value) is executed after 3 seconds. This.state. value points to the latest value

What if a class component wants to save the original value?

Read this.props before calling the event

You can see the online Demo

ShowMessage = (value) => {alert(" new value = "+ value); }; handleClick = () => { const { value } = this.state; setTimeout(() => this.showMessage(value), 3000); };Copy the code

It works, but when clicked it gets the current user, which is passed to this.showMessage, so that the value remains the same even 3 seconds later

Cons: Every time you need to get a value from this.props, if there is too much data, it is not human to write

2. Bind methods in constructors

You can see the online Demo

constructor(props) {
    super(props);
    this.showMessage = this.showMessage.bind(this);
    this.handleClick = this.handleClick.bind(this);
}
Copy the code

This method won’t solve the problem. Our problem was that we read the data from this.props too late — it wasn’t the context we needed to use when we read it

Use closures

Write methods into render so that each render captures the props or state being used at the time

You can see the online Demo

class ClassDemo extends React.Component { state = { value: "" }; render() { const { value } = this.state; Const showMessage = () => {alert(" new value = "+ value); }; const handleMessageChange = (e) => { this.setState({ value: e.target.value }); }; const handleClick = () => { setTimeout(showMessage, 3000); }; return ( <div> <input value={this.state.value} onChange={handleMessageChange} /> <button OnClick ={handleClick}> click </button> </div>); }}Copy the code

But that’s silly. What’s the difference between this and a functional component? Instead, use functional components

Functional components that want to keep the latest values

Use useRef to save the most recent value and let the component get the most recent value

function MyComponent() {
  const ref = useRef(null);
}
Copy the code

First, a REF plays the same role as an instance; the REF object is a container with the current property

We could have written the last example using functional components like this:

const FunctionDemo = () => { const [value, setValue] = useState(""); const refValue = useRef(""); Const showMessage = () => {alert(" last value = "+ refvalue.current); }; const handleMessageChange = (e) => { setValue(e.target.value); refValue.current = e.target.value; }; const handleClick = () => { setTimeout(showMessage, 3000); }; <div> <input value={value} onChange={handleMessageChange} /> <button onClick={handleClick}> click </button> </div> ); };Copy the code

You can see the online Demo

Here I put forward two questions:

  • Why does ref hold the latest value?
  • Why are functional components captured, but class components not?

The author’s answer will be given in subsequent articles

The resources

  • How is a functional component different from a class component?