如何判断ES6中是否存在this.setState?

时间:2017-01-08 13:25:03

标签: reactjs ecmascript-6 ecmascript-5

我一直在努力尝试将我的React代码从ES5迁移到ES6。正如我现在所知,this不再自动绑定,导致各种各样的地狱。

我试图通过反复试验弄清楚传递的对象是什么。到目前为止,我可以找到所有内容并相应地进但是当涉及到this.setState时,我遇到了问题,因为它在console.log中不可见 !!!!请参阅ES5中的屏幕截图:

enter image description here

这是ES6中的相同类型的代码: enter image description here

请教我如何捕鱼,即帮助我弄清楚如何理解物体何时具有this.setState?

我尝试过的事情

  1. 从谷歌搜索我明白你可以通过更改基本组件来default bind everything。不幸的是,当涉及this.setState时,这不起作用。它看起来与控制台中的this的ES5版本相同,所以我得出结论,setState仍然没有被绑定

4 个答案:

答案 0 :(得分:2)

过分简化this在JS中的工作方式:

  • 如果您将函数作为对象方法调用(例如,instance.foo()),则this将引用该对象实例。
  • 如果你自己调用一个函数(例如foo()),那么this可以是undefined,也可以是全局对象,具体取决于严格模式是否生效。
  • 如果你引用一个对象方法然后调用它,这意味着你自己调用它,即使它最初是一个对象方法。 (例如,var bar = instance.foo; bar();

再次,这是一个过于简单化; MDN有详细信息。

这适用于React,并且正如"Handling Events"上的React文档中所述:

  

您必须小心JSX回调中this的含义。在JavaScript中,默认情况下不会绑定类方法。如果您忘记绑定this.handleClick并将其传递给onClick,则在实际调用该函数时this将为undefined

在您的代码中,您将RawInput呈现为

 <RawInput value={this.state.value} updateValue={this.updateValue}/>

您正在将参考updateValue函数作为简单函数传递,因此this不会绑定updateValue

基本上,每当你将一个函数作为React prop传递时,除非你自己绑定它,否则它可能是一个错误。症状通常是this未定义。在你的代码中,它有点复杂:

this.props.updateValue(modifiedValue);

RawInput的updateValue属性是未绑定的函数App.updateValue,但由于您将其调用为this.props.updateValue,因此它被称为,就好像它是{{{ 1}} - 所以this.props引用RawInput的this。这就是为什么你的console.log显示的对象只有两个属性(propsstart):不是updateValue没有绑定或消失,而是setState 1}}没有绑定,因此updateValue不是您在this中所期望的。

要解决此问题,请参阅React文档解释:

  • 使用胖箭头功能:updateValue
  • 使用实验属性初始值设定项语法:将updateValue={(value) => this.updateValue(value)}替换为updateValue(modifiedValue) {...}
  • React文档中没有提到,但我经常使用的方法是:自己绑定updateValue = (modifiedValue) => {...}。例如:
updateValue

答案 1 :(得分:1)

你可以用以下代码替换console.log:

console.shallowCloneLog = function(){
    var typeString = Function.prototype.call.bind(Object.prototype.toString)
    console.log.apply(console, Array.prototype.map.call(arguments, function(x){
        switch (typeString(x).slice(8, -1)) {
            case 'Number': case 'String': case 'Undefined': case 'Null': case 'Boolean': return x;
            case 'Array': return x.slice();
            default:
                var out = Object.create(Object.getPrototypeOf(x));
                out.constructor = x.constructor;
                for (var key in x) {
                    out[key] = x[key];
                }
                Object.defineProperty(out, 'constructor', {value: x.constructor});
                return out;
        }
    }));
}

无论如何,关于你的问题,你可以添加这样的方法:

updateValue = () => {...}
在p POV中,es6很酷很棒。通过es6&#39;反应组件。上课没用。坚持使用createClass并且你会好起来的(如果你愿意,可以使用mixins!)

答案 2 :(得分:1)

试试Object.prototype.hasOwnProperty()。例如:

var X = function() {};
X.prototype.setSomething = 'a';
var x = new X();
x.setSomething; // log 'a' here
x.hasOwnPrperty('setSomething') // log false here

在您的情况下,只需console.log(this.hasOwnProperty('setState'))

答案 3 :(得分:1)

您必须将updateValue函数与组件绑定,才能拥有正确的上下文(this)。

在您的情况下,您的父类BaseComponent允许您使用类似的方法_bind

class App extends BaseComponent {
  constructor(props){
    super(props);
    this.state={value:'start'};
    this._bind('updateValue');
...