React踩坑记录之死循环

今天学习React的时候,一不小心踩到了坑,进入了无限死循环,导致直接溢出内存,报错
主要的原因就在于onClick事件中传入带参数的函数,应该传入函数的引用,而并非函数的调用
错误写法:在编写的时候,首在constructor函数中先进行this的绑定

			 this.toggleBtnClick = this.toggleBtnClick.bind(this);

然后进行onClick函数绑定事件的编写,错误点在为了函数传递参数,而在后面加了小括号。相当于在传参的同时,直接调用了该函数!

            <button onClick={this.toggleBtnClick(this.state.isToggleOn)}>
                {this.state.isToggleOn ? 'Button On' : 'Button Off'}
            </button>

这样的编写逻辑就会导致下面的死循环错误!

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
错误:超过最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,就会发生这种情况。React限制嵌套更新的数量,以防止无限循环。


//正确代码如下:
import React, {
    Component
} from 'react';
class ToggleBtnComp extends Component {
    constructor(props) {
        super(props)
        this.state = {
            isToggleOn: true
        }    
}
    render() {
        // console.log(this);
        return (
            <button onClick={this.toggleBtnClick.bind(this, this.state.isToggleOn)}>
                {this.state.isToggleOn ? 'Button On' : 'Button Off'}
            </button>
        );
    }
    toggleBtnClick(isToggleOn, e) {
        console.log('Now state is' + isToggleOn + ' before to convert.');
        this.setState({
            isToggleOn: !isToggleOn
        })

    }
}

export default ToggleBtnComp;

分析一下程序整体执行流程:当组件ToggleBtnCompindex中被渲染的时候,相当于new了一个实例,必然会调用constructor构造函数。其中render函数属于生命周期函数,也必然会被执行。在render函数里面必然会解析return里面的内容。当解析到Button的时候,发现有一个点击事件。React框架就会自动解析和执行onClick里面的代码。如果里面是方法的调用,那么一进行解析,就会执行里面的代码。当我们的代码正在进行解析的时候,绑定点击事件的代码就被执行,显然这样是不合适的。而且在事件函数中我们又使用了setState,重新更新了状态属性,紧接着再次进行页面的渲染,周而复始,终导致死循环,内存溢出。所以我们应该等到点击按下的时候,再执行里面的函数内容。所以绑定的事件里面应该传入事件的引用,或者利用箭头函数进行书写。


onClick函数里面的两种书写方式

写法1. 传入事件的引用,并进行传参(需要绑定this,否则引用中的this指向调用者button)

		<button onClick={this.toggleBtnClick.bind(this,this.state.isToggleOn)}>
			{this.state.isToggleOn ? 'Button On' : 'Button Off'}
		</button>

写法2. 箭头函数(无需绑定this,在箭头函数中this自然指向ToggleBtnComp)

        <button onClick={() => this.toggleBtnClick(this.state.isToggleOn)}>
            {this.state.isToggleOn ? 'Button On' : 'Button Off'}
        </button>

总结:原先方法的直接调用,导致了setState函数更新状态后,进行render,又会重新触发onClick中函数的调用,从而会不停地进行render渲染。使用以上两种编写方式进行修改后,便可实现最初效果(点击后再进行方法的调用)。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值