React学习笔记——函数Function组件和类Class组件的setState的区别

关于React中函数Function组件和类Class组件的相同点和区别点,我想大家都已经知晓了,比如:

1、相同点

  • 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props
  • 所有 React 组件都必须是纯函数,并禁止修改其自身 props
  • React是单项数据流,父组件改变了属性,那么子组件视图会更新。、
  • 父组件props有变化时,子组件随之而改变
  • 属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改
  • 组件的属性和状态改变都会更新视图。

2、不同点

区别函数组件类组件
生命周期没有
this没有
state没有
改变stateHook:useStatethis.setState()
性能高(不用实例化)低(需要实例化)

3、案例

(1)类class组件

不过,今天同事问了我一个简单的代码问题,之前也没认真想过,一下子没回答出来。
话不多说,看一下:

import React, { Component } from 'react'
class App extends Component {
    state={
        number:0
    }
    handleClick=()=>{
       for(let i = 0 ;i<5;i++){
           setTimeout(()=>{
               this.setState({ number:this.state.number+1 })
               console.log(this.state.number)
           },1000)
       }
    }
    render(){
        return(
            <div>
                当前的number:{this.state.number}
                <button onClick={this.handleClick}>点击我</button>
            </div>
        )
    }
}
export default App

在这里插入图片描述

(2)函数组件
import React ,{ useState } from 'react';
const App = () => {
    const [ num ,setNumber ] = useState(0)
    const handleClick1 = ()=> {
        for(let i=0; i<5;i++ ){
           setTimeout(() => {
                setNumber(num+1)
                console.log(num)
           }, 1000)
        }
    }
    return (
        <div>
            当前的num值:{num}
            <br/>
            <button onClick={handleClick1}>改变num</button>
        </div>
    );
};
export default App;

在这里插入图片描述

(3)对比结果

可以看出:
第一个类class组件,打印结果是:1 2 3 4 5,页面上显示的是5;
第二个函数Function组件,打印结果是:0 0 0 0 0,页面上显示的是1

这个结果看上去很唬人,认真分析一下:

  • 类class组件中,通过一个实例化的class,去维护组件中的各种状态。点击按钮,循环五次setTimeout,同时由于setState没有在react正常的函数里执行上下文,而是位于异步的setTimeout里面,所以批量更新的条件被破坏,可以同步拿到每次setState之后的值
    关于React批量更新可查看React学习笔记——this.setState的基础使用和不同传参方法详解
  • 函数Function组件中,没有一个状态去保存这些信息,它只是一个函数,每一次函数上下文执行,所有变量,常量都重新声明,执行完毕,再被垃圾机制回收。所以如上,无论setTimeout执行多少次,都是在当前函数上下文执行,此时num = 0不会变,之后setNumber执行,函数组件重新执行之后,num才变化。

结论:

  • 所以, 对于class组件,我们只需要实例化一次,实例中保存了组件的state等状态。对于每一次更新只需要调用render方法就可以。
  • 但是在function组件中,我们每一次更新都是一次新的函数执行,为了保存一些状态,执行一些副作用钩子,react-hooks应运而生,去帮助记录组件的状态,处理一些额外的副作用。

4、有趣拓展

对于函数Function的写法,在set的时候有函数型和对象型两种写法,我们观察一下这两种的区别:

import React ,{ useState } from 'react';
const App = () => {
    const [ num ,setNumber ] = useState(0)
    const [ val ,setVal ] = useState(0)
    const handleClick1 = ()=> {
        for(let i=0; i<5;i++ ){
           setTimeout(() => {
                setNumber(num+1)
                console.log('num',num)
                
           }, 1000)
        }
    }
    const handleClick2 = () =>{
        for(let i=0; i<5;i++ ){
            setTimeout(() => {
                 setVal(val=>val+1)
                 console.log('val',val)
            }, 1000)
        }
    }
    return (
        <div>
            当前的num值:{num}
            <br/>
            <button onClick={handleClick1}>改变num</button>
            <br/>
            当前的val值:{val}
            <br/>
            <button onClick={handleClick2}>改变val</button>
        </div>
    );
};
export default App;

在这里插入图片描述
可以看出,当里面是函数式的写法时,虽然每次打印的val值是0,但是他会依赖于上一次的状态,所以val值每次都会+1;而对象式的写法却不会。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 React 中,有两种类型的组件:类组件函数组件。这两种组件的主要区别在于它们的定义方式和内部实现。在类组件中,我们可以使用 `setState()` 方法来更新组件的状态,而在函数组件中,我们可以使用 `useState()` 钩子来管理组件的状态。 虽然 `setState()` 和 `useState()` 都可以用来更新组件的状态,但它们的实现方式略有不同。下面是它们之间的一些主要区别: 1. 类组件中的 `setState()` 是异步的,而函数组件中的 `useState()` 是同步的。这意味着,在类组件中调用 `setState()` 后,React 并不会立即更新组件的状态,而是将更新添加到更新队列中,并在下一次渲染时才会应用这些更新。在函数组件中,当调用 `useState()` 时,React 会立即更新组件的状态并重新渲染组件。 2. 类组件中的 `setState()` 可以接受一个回调函数作为参数,在状态更新完毕后执行。这个回调函数可以用来处理一些依赖于新状态的操作,比如执行某些动画或发送网络请求。在函数组件中,我们可以使用 `useEffect()` 钩子来达到相同的效果。 3. 当通过 `setState()` 更新组件的状态时,React 会将新的状态合并到原来的状态中。这意味着,不需要在每次更新时重新指定完整的状态对象。在函数组件中,由于 `useState()` 钩子返回的状态值是一个单独的变量,因此我们需要手动合并状态,或者使用 `useReducer()` 钩子来处理复杂的状态逻辑。 总之,虽然 `setState()` 和 `useState()` 都可以用来更新组件的状态,但它们的实现方式和使用方法略有不同。在选择使用哪种方式时,需要考虑到组件的类型以及状态更新的具体需求。 ### 回答2: 在React中,类组件函数组件都可以使用`setState`方法来更新组件的状态。然而,在使用上有一些不同之处。 1. 类组件的`setState`方法是一个异步函数,它将状态改变合并并批量执行,以提高性能。因此,连续多次调用`setState`会将状态合并为一次更新。例如: ```jsx this.setState({ count: 1 }); this.setState({ count: 2 }); ``` 最终,状态`count`将被更新为2。 2. 函数组件的`setState`方法是同步执行的。每次调用`setState`,都会立即更新状态并重新渲染组件。因此,连续多次调用`setState`会触发多次重新渲染。例如: ```jsx const [count, setCount] = useState(0); setCount(1); setCount(2); ``` 因为函数组件的状态是独立的,所以每次调用`setCount`都会重新渲染组件,并使状态`count`更新为2。 3. 类组件的`setState`方法可以传入一个回调函数作为参数,用于在状态更新完成后执行其他操作。例如: ```jsx this.setState({ count: 1 }, () => { console.log('状态更新完成'); }); ``` 回调函数将在状态更新完成后执行。这对于需要在更新状态后执行特定操作的情况很有用。 4. 函数组件的`setState`方法没有回调函数的选项,如果需要在状态更新后执行操作,可以使用`useEffect`钩子函数。例如: ```jsx useEffect(() => { console.log('状态更新完成'); }, [count]); ``` 在`useEffect`的依赖数组中传入状态`count`,当`count`更新时,`useEffect`中的回调函数将被触发。 综上所述,类组件函数组件在使用`setState`方法上有一些不同之处。使用时可以根据具体情况选择适合的组件类型。 ### 回答3: React中的类组件函数组件之间在使用`setState`时有一些区别。 在类组件中,我们可以直接访问和更新组件的状态。使用`setState`方法可以更新状态,并触发组件的重新渲染。`setState`方法是异步的,并且会将新的状态合并到当前状态中。它接受一个对象或者一个函数作为参数。当传递一个对象时,该对象会与当前状态合并;而当传递一个函数时,函数接收先前的状态作为参数,并返回一个新的状态对象。需要注意的是,由于`setState`是异步的,所以不能保证状态立即更新,如果需要在状态更新后执行一些操作,可以在`setState`的回调函数中进行。 在函数组件中,使用`useState`方法来定义和更新状态。`useState`返回一个数组,第一个元素是当前状态的值,第二个元素是一个更新状态的函数。使用`useState`定义的状态只是一个独立的值,并不会与其他状态进行合并。在更新状态时,使用状态更新函数传入新的状态值。与`setState`不同的是,`useState`不会合并和更新状态,它始终会完全替换掉当前状态。在函数组件中,每次重新渲染时,状态都是独立的。 因此,类组件的`setState`可以合并多个状态变化,并且是异步的,需要在回调函数中处理更新后的状态;而函数组件的`useState`每次更新状态都会替换掉当前状态,并且是同步的。选择使用哪种方式取决于具体的需求和组件的复杂性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值