为什么说不要滥用setState

本文探讨了React中setState的使用对组件性能的影响,强调了合理使用setState以减少不必要的渲染次数的重要性。通过实例对比,展示了如何将多个状态更新合并为一次setState调用,以及如何正确使用setState的函数形式来确保状态更新的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

setState 成本比较高,每setState一次都会调用render渲染一次,setState会影响性能
如下面调用了四个setState,那么会render四次

import React,{ Component } from 'react';
class index extends Component {
    constructor(props) {
        //构造函数
        super(props);
        this.state = { 
            date: new Date(),
            count01:0,
            count02:10,
            count03:100,
         }
         console.log("contructor-->",props)    
    };
     tick=()=>{
        console.log("tick->called")
        this.setState({
            date: new Date()
        })
        this.setState({
            count01:this.state.count01++
        })
        this.setState({
            count02:this.state.count02++
        })
        this.setState({
            count03:this.state.count03++
        })
    }
    componentDidMount(){
        console.log("DidMount")
        this.timer = setInterval(() =>{
            this.tick()
        },1000)
    }
        render() {
        console.log("render-->",this.state)
        const {date} = this.state;
        return (
        <h2>现在是:{date.toLocaleTimeString()}</h2>
        );
    }
}
export default index;

因为上面设置了定时器,每秒会执行一次tick(),红框中是执行一次tick()打印出来的
在这里插入图片描述
所以,为了提高组件性能,尽量一次把所有要改变的值放到同一个setState里面

import React,{ Component } from 'react';
class index extends Component {
    constructor(props) {
        //构造函数
        super(props);
        this.state = { 
            date: new Date(),
            count01:0,
            count02:10,
            count03:100,
         }
         console.log("contructor-->",props)    
    };
     tick=()=>{
        console.log("tick->called")
         this.setState({
            date: new Date(),
            count01:this.state.count01++,
            count02:this.state.count02++,
            count03:this.state.count03++
        })
    }
    componentDidMount(){
        console.log("DidMount")
        this.timer = setInterval(() =>{
            this.tick()
        },1000)
    }
        render() {
        console.log("render-->",this.state)
        const {date} = this.state;
        return (
        <h2>现在是:{date.toLocaleTimeString()}</h2>
        );
    }
}
export default index;

在这里插入图片描述
这里需要注意的是,this.props 和this.state可能是一部更新的,不应该依靠它们的值来计算下一个状态。
例如上面的 count01:this.state.count01++,可能无法更新,要修复它,要使用第二种形态的setState()来接收一个函数而不是一个对象,该函数将接收先前的状态作为第一个参数(pre),将此次更新被应用时的props作为第二个参数(参数名可以自己设置)

this.setState((pre,props)=>({
            date: new Date(),
            count01:pre.count01 +1,
            count02:pre.count02 +1,
            count03:pre.count03 +1
        }))

原本是写成

this.setState((pre,props)=>({
            date: new Date(),
            count01:pre.count01 ++,
            count02:pre.count02 ++,
            count03:pre.count03 ++
        }))

因为++是先赋值再加,等于没变,所以 ++ 无效,所以换成了+1
另外要避免直接将props中的属性赋值给state中的属性

this.state = {
	name = this.props.name //尽量避免使用这种方法,props改变时name 不会更新
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值