对于一个碰运气解决的问题,来询问一下问题产生的原因



  • 之前运行程序等了半天也没渲染出界面,之后报错如下:

    0_1471515937063_error2.png

    当时我是懵逼的,我这么小一个程序也能栈溢出。。。

    后来修改了两个地方,具体如下:

    0_1471516171657_code.png

    之前的写法是onPress={this.clearUserMsg()}和onPress={this.refreshPage()}

    函数原型如下:
    clearUserMsg(){
    this.setState({user:null});
    }
    refreshPage(){
    this.setState({id:1});
    }

    改完之后Reload时渲染界面快了很多,我之前没接触过js,不清楚this的绑定具体有什么用,绑定在这里起的作用又是什么,望大神指点!谢过!


  • administrators

    maximum call stack size exceeded是指堆栈溢出
    堆栈为什么会溢出呢,一般是死循环,函数一个接一个入栈,到爆掉内存为止

    你的写法为什么会死循环呢
    一个函数,后面如果跟上括号 即 函数()
    表示函数立即执行

    当你写下onPress={this.某方法()} 表示 这个组件在渲染的时候 就执行了某方法。
    很不幸,你这个方法同时还调用了setState,setState触发render,render中组件重新渲染,于是又触发某方法——死循环

    onPress要求的是一个函数,是在用户press的时候执行(之后的某个时刻),而不是在渲染时候立即执行,所以重点是:不要加括号立即执行!

    关于绑定this的解释看这里 http://bbs.reactnative.cn/topic/129/



  • @打得不错 我就补充一下,首先是之前的写法有问题,但是如果去掉括号就会不执行,原因在于function未绑定到当前实例中,你无法调用。
    建议你采用ES6的lamda语法,将前面两个函数改成如下:
    clearUserMsg=()=>{
    this.setState({user:null});
    }
    refreshPage同样如此。这时候你就可以不用 bind(this)进行函数绑定了。



  • 第一种写法,是直接调用函数,而不是给一个函数地址。你函数名后面加入了(),那么js解析到控件这一行,会立即执行。bind只是绑定函数的写法,不会立即调用。



  • @sunnylqm 懂了,原来是这样造成的死循环,this的绑定也懂了一些,感谢!!



  • @chenakira 按你说的试了一下去掉括号,确实不能执行,没绑定this上下文就不对,再按你说的改用了箭头函数果然成功了。

    查了一下资料,原来箭头函数没有自己的this,所以在函数生成的时候函数里的this就已经绑定上下文了,真方便,谢谢你!



  • @coyer 嗯,懂了,初学者感觉这一块儿的水有点深啊,谢谢你!



  • @打得不错 说:

    onPress={this.refreshPage()}

    onPress={this.refreshPage()} 直接被执行了,所以你这里相当于死循环了。

    this.refreshPage.bind( this ) 并没有执行 refreshPage 只是帮他绑定了一个执行作用域


登录后回复