The difference between function components and class components in react

Function components and class components

function component

The function component is stateless , and every time the data is updated, the function will be called again to generate a new function execution context

So before the appearance of hooks, most of the function components can only be used as pure display components, because it has no storage state (state), no life cycle, and logic cannot be reused

Writing functional components is called functional programming

class component

Class components are based on classes in es6, and writing class components is called object-oriented programming

Class components are stateful and have their own life cycle

Before hooks appeared, components with complex logic or state-dependent components were all in the form of class components

So what is the essential difference between them?

Look directly at the code

class component

class Index extends React.Component<any,any>{
    constructor(props){
        super(props)
        this.state={
            number:0
        }
    }
    handerClick=()=>{
       for(let i = 0 ;i<5;i++){
           setTimeout(()=>{
               this.setState({ number:this.state.number+1 })
               console.log(this.state.number)
           },1000)
       }
    }

    render(){
        return <div>
            <button onClick={ this.handerClick } >num++</button>
        </div>
    }
}

function component

function Index(){
    const [ num ,setNumber ] = React.useState(0)
    const handerClick=()=>{
        for(let i=0; i<5;i++ ){
           setTimeout(() => {
                setNumber(num+1)
                console.log(num)
           }, 1000)
        }
    }
    return <button onClick={ handerClick } >{ num }</button>
}

What results will the above two code snippets print respectively?

First example: 0 0 0 0 0

Second example: 0 0 0 0 0


Let's explain the first example first

The first example is in the form of a class component

Initialize a named numberstate with an initial value of 0

Click the button to execute handerClickthe method, trigger the update of the number, use the loop increment method in the update function, and add a delay of 1000ms

In the react18 version, react automatically batches the state update , that is to say, the same state is updated multiple times in a short period of time, and react will only update the state based on the state value before the update

this.state = {
    number: 0
}
this.setState({number:this.state.number+1})
this.setState({number:this.state.number+1})
this.setState({number:this.state.number+1})
//此时number的值:1

The above code is equivalent to executing three times

this.setState({number:0 +1})

Because the value of this.state.number is always 0 in a short time ! (In the final analysis, it is because setState is asynchronous )

so we can understand

The number printed in a short time is always 0

But we assume that react does not automatically batch the state

What will be the output?

The answer is : 1 2 3 4 5

In the final analysis, the state is saved, and each setState will be incremented based on the previous state

No matter what react does to the state, what we need to know is that the class component is stateful, and its state will always be saved in the component life cycle


Let's look at the second example: function components

This should be easier to understand for those familiar with closures

Using the setTimeOut callback in the for loop will generate a closure, and the num in the closure will point to the num in the scope of the original function, which is 0

So every time we execute, we setNumber(num + 1)actually execute setNumber(0 + 1), execute console.log(num); actually executeconsole.log(0)

After the loop ends, the value of num will become 1, because setNumber(0 + 1)num is set to 1 after execution


Let's sort out the process of executing setNumber once:

  1. After executing setNumber, it will cause the component function to be restarted, and all statements will be called and executed again

  2. When going to useState, react actually went to updateState inside, and got the latest state: 1, everything is normal at this time

  3. Go to handerClick, at this time handerClick is recreated, that is, handerClick points to a new memory space, it is worth noting that: when the for loop goes down, the context where num is located is not the current function (newly created function), but It is a function created during the first initialization, and in the context of that function, num is always 0, so the console.log output is 0

On the contrary: class writing, state changes handerClick has not been recreated, and this point has not changed

Guess you like

Origin blog.csdn.net/Laollaoaolao/article/details/126243421