Chrome, Firefox debuggers not displaying the correct value for 'this' in a react app












4















Here's a bit of code, within a react component class (scaffolded using CRA 2)



  click = () => {
console.log(this, "hello");
let x = 1 + 1; //This is just here to let chrome put a break point here.
}


When this code runs, it will print the component object to the console.



However - if I attach a debugger to that point, both Chrome (68), and Firefox (63) will show 'this' as undefined.



What's going on here?



Is it something to do with the transform-class-properties babel plugin being used to create click as a class property?



Edit: Yes, that seems like exactly what it is.



If we manually bind the method like:



  constructor() {
super();
this.click2 = this.click2.bind(this);
}

click2() {
console.log(this, "hello");
let x = 1 + 1;
}


then it works fine.



In any case - is there a convenient way to solve this, so I don't have to put all those bind statements in?










share|improve this question




















  • 1





    I'd start by looking at what the transpiled code looks like

    – CertainPerformance
    Nov 28 '18 at 6:32











  • Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

    – Ahmad
    Nov 28 '18 at 6:33











  • Can you post what the transpiled code looks like?

    – CertainPerformance
    Dec 2 '18 at 5:01











  • @CertainPerformance - How would I do that? Given that we're talking about the dev server here.

    – dwjohnston
    Dec 3 '18 at 23:54











  • I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

    – Aravindan Ve
    Dec 5 '18 at 21:26
















4















Here's a bit of code, within a react component class (scaffolded using CRA 2)



  click = () => {
console.log(this, "hello");
let x = 1 + 1; //This is just here to let chrome put a break point here.
}


When this code runs, it will print the component object to the console.



However - if I attach a debugger to that point, both Chrome (68), and Firefox (63) will show 'this' as undefined.



What's going on here?



Is it something to do with the transform-class-properties babel plugin being used to create click as a class property?



Edit: Yes, that seems like exactly what it is.



If we manually bind the method like:



  constructor() {
super();
this.click2 = this.click2.bind(this);
}

click2() {
console.log(this, "hello");
let x = 1 + 1;
}


then it works fine.



In any case - is there a convenient way to solve this, so I don't have to put all those bind statements in?










share|improve this question




















  • 1





    I'd start by looking at what the transpiled code looks like

    – CertainPerformance
    Nov 28 '18 at 6:32











  • Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

    – Ahmad
    Nov 28 '18 at 6:33











  • Can you post what the transpiled code looks like?

    – CertainPerformance
    Dec 2 '18 at 5:01











  • @CertainPerformance - How would I do that? Given that we're talking about the dev server here.

    – dwjohnston
    Dec 3 '18 at 23:54











  • I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

    – Aravindan Ve
    Dec 5 '18 at 21:26














4












4








4


1






Here's a bit of code, within a react component class (scaffolded using CRA 2)



  click = () => {
console.log(this, "hello");
let x = 1 + 1; //This is just here to let chrome put a break point here.
}


When this code runs, it will print the component object to the console.



However - if I attach a debugger to that point, both Chrome (68), and Firefox (63) will show 'this' as undefined.



What's going on here?



Is it something to do with the transform-class-properties babel plugin being used to create click as a class property?



Edit: Yes, that seems like exactly what it is.



If we manually bind the method like:



  constructor() {
super();
this.click2 = this.click2.bind(this);
}

click2() {
console.log(this, "hello");
let x = 1 + 1;
}


then it works fine.



In any case - is there a convenient way to solve this, so I don't have to put all those bind statements in?










share|improve this question
















Here's a bit of code, within a react component class (scaffolded using CRA 2)



  click = () => {
console.log(this, "hello");
let x = 1 + 1; //This is just here to let chrome put a break point here.
}


When this code runs, it will print the component object to the console.



However - if I attach a debugger to that point, both Chrome (68), and Firefox (63) will show 'this' as undefined.



What's going on here?



Is it something to do with the transform-class-properties babel plugin being used to create click as a class property?



Edit: Yes, that seems like exactly what it is.



If we manually bind the method like:



  constructor() {
super();
this.click2 = this.click2.bind(this);
}

click2() {
console.log(this, "hello");
let x = 1 + 1;
}


then it works fine.



In any case - is there a convenient way to solve this, so I don't have to put all those bind statements in?







javascript debugging browser babeljs create-react-app






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 6:36







dwjohnston

















asked Nov 28 '18 at 6:30









dwjohnstondwjohnston

2,907114994




2,907114994








  • 1





    I'd start by looking at what the transpiled code looks like

    – CertainPerformance
    Nov 28 '18 at 6:32











  • Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

    – Ahmad
    Nov 28 '18 at 6:33











  • Can you post what the transpiled code looks like?

    – CertainPerformance
    Dec 2 '18 at 5:01











  • @CertainPerformance - How would I do that? Given that we're talking about the dev server here.

    – dwjohnston
    Dec 3 '18 at 23:54











  • I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

    – Aravindan Ve
    Dec 5 '18 at 21:26














  • 1





    I'd start by looking at what the transpiled code looks like

    – CertainPerformance
    Nov 28 '18 at 6:32











  • Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

    – Ahmad
    Nov 28 '18 at 6:33











  • Can you post what the transpiled code looks like?

    – CertainPerformance
    Dec 2 '18 at 5:01











  • @CertainPerformance - How would I do that? Given that we're talking about the dev server here.

    – dwjohnston
    Dec 3 '18 at 23:54











  • I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

    – Aravindan Ve
    Dec 5 '18 at 21:26








1




1





I'd start by looking at what the transpiled code looks like

– CertainPerformance
Nov 28 '18 at 6:32





I'd start by looking at what the transpiled code looks like

– CertainPerformance
Nov 28 '18 at 6:32













Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

– Ahmad
Nov 28 '18 at 6:33





Are you sure each inherited instance doesn't get two sets of click2 events attached to it?

– Ahmad
Nov 28 '18 at 6:33













Can you post what the transpiled code looks like?

– CertainPerformance
Dec 2 '18 at 5:01





Can you post what the transpiled code looks like?

– CertainPerformance
Dec 2 '18 at 5:01













@CertainPerformance - How would I do that? Given that we're talking about the dev server here.

– dwjohnston
Dec 3 '18 at 23:54





@CertainPerformance - How would I do that? Given that we're talking about the dev server here.

– dwjohnston
Dec 3 '18 at 23:54













I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

– Aravindan Ve
Dec 5 '18 at 21:26





I think transform-class-properties puts all your class property functions into the constructor, and since the debugger is in a sub scope this probably happens: stackoverflow.com/questions/28388530/…

– Aravindan Ve
Dec 5 '18 at 21:26












3 Answers
3






active

oldest

votes


















4





+100









I created an example on CodeSandbox that I think reproduces your issue, though I'm not sure. Please create your own example if it does not. The relevant code is included below.



In this example, the code works fine. console.log(this, "hello") logs a Square object + "hello" as you might expect. If you put a breakpoint on the let y = 2 + 2 line, the Chrome debugger will show



this: undefined
x: 2
y: undefined


Of course, y is undefined because the let y statement has not executed yet. x is defined, as expected. this is undefined because React and Babel are jumping through lots of hoops under the covers, and this is, in fact, undefined. If you want to access this from the debugger, you need to use _this. In fact, even though you put a breakpoint on the line let y = 2 + 2, that is not the actual source being executed or where the actual breakpoint is. What you are seeing is a convenience provided by a source map that lets you view and set a breakpoint on the code you wrote despite the fact that the actual code being run is completely different (the result of processing by Babel etc.).



The code I wrote is:



class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null
};
}

click = () => {
console.log(this, "hello");
let x = 1 + 1; //This is just here to let chrome put a break point here.
let y = 2 + 2; //This is just here to let chrome put a break point here.
};

render() {
return (
<button className="square" onClick={this.click}>
{this.props.value}
</button>
);
}
}


the code actually running is:



var Square =
/*#__PURE__*/
function (_React$Component) {
(0, _inherits2.default)(Square, _React$Component);

function Square(props) {
var _this;

(0, _classCallCheck2.default)(this, Square);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Square).call(this, props));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "click", function () {
console.log((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hello");
var x = 1 + 1; //This is just here to let chrome put a break point here.

var y = 2 + 2; //This is just here to let chrome put a break point here.
});
_this.state = {
value: null
};
return _this;
}

(0, _createClass2.default)(Square, [{
key: "render",
value: function render() {
return _react.default.createElement("button", {
className: "square",
onClick: this.click
}, this.props.value);
}
}]);
return Square;
}(_react.default.Component);


Because of the React.js internals (in particular, the way it wraps events), by the time the handler is called, this is undefined. If you look at the call stack, you see that executeDispatch calls invokeGuardedCallbackAndCatchFirstError with an explicit value of undefined for the context object that is ultimately the value of this inside the callback. React and Babel try to hide all this from you when you are writing code, but they cannot completely hide this from the debugger, particularly with respect to this, so in this case you have to go to the actual code to see that you need to refer to _this in the debugger.






share|improve this answer


























  • Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

    – dwjohnston
    Dec 9 '18 at 23:25











  • This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

    – dwjohnston
    Dec 10 '18 at 6:20













  • @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

    – Old Pro
    Dec 12 '18 at 21:44











  • Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

    – dwjohnston
    Dec 12 '18 at 23:24











  • @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

    – Old Pro
    Dec 13 '18 at 5:14



















0














I think you need to set babel options to disable module processing. See this answer:



How to stop babel from transpiling 'this' to 'undefined'



In your .babelrc:



{
"presets": [
[ "es2015", { "modules": false } ]
]
}





share|improve this answer
























  • Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

    – dwjohnston
    Dec 10 '18 at 6:21



















0














An pragmatic alternative - if what you're wanting to do is inspect the state/props of a react component at a certain point, is to enter the break point as per normal - but instead of using the debugger to inspect the state - use the react dev tools plugin to actually examine the state.



This might prove to be a bit fiddly, but it's an option.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53513424%2fchrome-firefox-debuggers-not-displaying-the-correct-value-for-this-in-a-react%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4





    +100









    I created an example on CodeSandbox that I think reproduces your issue, though I'm not sure. Please create your own example if it does not. The relevant code is included below.



    In this example, the code works fine. console.log(this, "hello") logs a Square object + "hello" as you might expect. If you put a breakpoint on the let y = 2 + 2 line, the Chrome debugger will show



    this: undefined
    x: 2
    y: undefined


    Of course, y is undefined because the let y statement has not executed yet. x is defined, as expected. this is undefined because React and Babel are jumping through lots of hoops under the covers, and this is, in fact, undefined. If you want to access this from the debugger, you need to use _this. In fact, even though you put a breakpoint on the line let y = 2 + 2, that is not the actual source being executed or where the actual breakpoint is. What you are seeing is a convenience provided by a source map that lets you view and set a breakpoint on the code you wrote despite the fact that the actual code being run is completely different (the result of processing by Babel etc.).



    The code I wrote is:



    class Square extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    value: null
    };
    }

    click = () => {
    console.log(this, "hello");
    let x = 1 + 1; //This is just here to let chrome put a break point here.
    let y = 2 + 2; //This is just here to let chrome put a break point here.
    };

    render() {
    return (
    <button className="square" onClick={this.click}>
    {this.props.value}
    </button>
    );
    }
    }


    the code actually running is:



    var Square =
    /*#__PURE__*/
    function (_React$Component) {
    (0, _inherits2.default)(Square, _React$Component);

    function Square(props) {
    var _this;

    (0, _classCallCheck2.default)(this, Square);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Square).call(this, props));
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "click", function () {
    console.log((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hello");
    var x = 1 + 1; //This is just here to let chrome put a break point here.

    var y = 2 + 2; //This is just here to let chrome put a break point here.
    });
    _this.state = {
    value: null
    };
    return _this;
    }

    (0, _createClass2.default)(Square, [{
    key: "render",
    value: function render() {
    return _react.default.createElement("button", {
    className: "square",
    onClick: this.click
    }, this.props.value);
    }
    }]);
    return Square;
    }(_react.default.Component);


    Because of the React.js internals (in particular, the way it wraps events), by the time the handler is called, this is undefined. If you look at the call stack, you see that executeDispatch calls invokeGuardedCallbackAndCatchFirstError with an explicit value of undefined for the context object that is ultimately the value of this inside the callback. React and Babel try to hide all this from you when you are writing code, but they cannot completely hide this from the debugger, particularly with respect to this, so in this case you have to go to the actual code to see that you need to refer to _this in the debugger.






    share|improve this answer


























    • Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

      – dwjohnston
      Dec 9 '18 at 23:25











    • This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

      – dwjohnston
      Dec 10 '18 at 6:20













    • @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

      – Old Pro
      Dec 12 '18 at 21:44











    • Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

      – dwjohnston
      Dec 12 '18 at 23:24











    • @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

      – Old Pro
      Dec 13 '18 at 5:14
















    4





    +100









    I created an example on CodeSandbox that I think reproduces your issue, though I'm not sure. Please create your own example if it does not. The relevant code is included below.



    In this example, the code works fine. console.log(this, "hello") logs a Square object + "hello" as you might expect. If you put a breakpoint on the let y = 2 + 2 line, the Chrome debugger will show



    this: undefined
    x: 2
    y: undefined


    Of course, y is undefined because the let y statement has not executed yet. x is defined, as expected. this is undefined because React and Babel are jumping through lots of hoops under the covers, and this is, in fact, undefined. If you want to access this from the debugger, you need to use _this. In fact, even though you put a breakpoint on the line let y = 2 + 2, that is not the actual source being executed or where the actual breakpoint is. What you are seeing is a convenience provided by a source map that lets you view and set a breakpoint on the code you wrote despite the fact that the actual code being run is completely different (the result of processing by Babel etc.).



    The code I wrote is:



    class Square extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    value: null
    };
    }

    click = () => {
    console.log(this, "hello");
    let x = 1 + 1; //This is just here to let chrome put a break point here.
    let y = 2 + 2; //This is just here to let chrome put a break point here.
    };

    render() {
    return (
    <button className="square" onClick={this.click}>
    {this.props.value}
    </button>
    );
    }
    }


    the code actually running is:



    var Square =
    /*#__PURE__*/
    function (_React$Component) {
    (0, _inherits2.default)(Square, _React$Component);

    function Square(props) {
    var _this;

    (0, _classCallCheck2.default)(this, Square);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Square).call(this, props));
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "click", function () {
    console.log((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hello");
    var x = 1 + 1; //This is just here to let chrome put a break point here.

    var y = 2 + 2; //This is just here to let chrome put a break point here.
    });
    _this.state = {
    value: null
    };
    return _this;
    }

    (0, _createClass2.default)(Square, [{
    key: "render",
    value: function render() {
    return _react.default.createElement("button", {
    className: "square",
    onClick: this.click
    }, this.props.value);
    }
    }]);
    return Square;
    }(_react.default.Component);


    Because of the React.js internals (in particular, the way it wraps events), by the time the handler is called, this is undefined. If you look at the call stack, you see that executeDispatch calls invokeGuardedCallbackAndCatchFirstError with an explicit value of undefined for the context object that is ultimately the value of this inside the callback. React and Babel try to hide all this from you when you are writing code, but they cannot completely hide this from the debugger, particularly with respect to this, so in this case you have to go to the actual code to see that you need to refer to _this in the debugger.






    share|improve this answer


























    • Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

      – dwjohnston
      Dec 9 '18 at 23:25











    • This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

      – dwjohnston
      Dec 10 '18 at 6:20













    • @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

      – Old Pro
      Dec 12 '18 at 21:44











    • Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

      – dwjohnston
      Dec 12 '18 at 23:24











    • @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

      – Old Pro
      Dec 13 '18 at 5:14














    4





    +100







    4





    +100



    4




    +100





    I created an example on CodeSandbox that I think reproduces your issue, though I'm not sure. Please create your own example if it does not. The relevant code is included below.



    In this example, the code works fine. console.log(this, "hello") logs a Square object + "hello" as you might expect. If you put a breakpoint on the let y = 2 + 2 line, the Chrome debugger will show



    this: undefined
    x: 2
    y: undefined


    Of course, y is undefined because the let y statement has not executed yet. x is defined, as expected. this is undefined because React and Babel are jumping through lots of hoops under the covers, and this is, in fact, undefined. If you want to access this from the debugger, you need to use _this. In fact, even though you put a breakpoint on the line let y = 2 + 2, that is not the actual source being executed or where the actual breakpoint is. What you are seeing is a convenience provided by a source map that lets you view and set a breakpoint on the code you wrote despite the fact that the actual code being run is completely different (the result of processing by Babel etc.).



    The code I wrote is:



    class Square extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    value: null
    };
    }

    click = () => {
    console.log(this, "hello");
    let x = 1 + 1; //This is just here to let chrome put a break point here.
    let y = 2 + 2; //This is just here to let chrome put a break point here.
    };

    render() {
    return (
    <button className="square" onClick={this.click}>
    {this.props.value}
    </button>
    );
    }
    }


    the code actually running is:



    var Square =
    /*#__PURE__*/
    function (_React$Component) {
    (0, _inherits2.default)(Square, _React$Component);

    function Square(props) {
    var _this;

    (0, _classCallCheck2.default)(this, Square);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Square).call(this, props));
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "click", function () {
    console.log((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hello");
    var x = 1 + 1; //This is just here to let chrome put a break point here.

    var y = 2 + 2; //This is just here to let chrome put a break point here.
    });
    _this.state = {
    value: null
    };
    return _this;
    }

    (0, _createClass2.default)(Square, [{
    key: "render",
    value: function render() {
    return _react.default.createElement("button", {
    className: "square",
    onClick: this.click
    }, this.props.value);
    }
    }]);
    return Square;
    }(_react.default.Component);


    Because of the React.js internals (in particular, the way it wraps events), by the time the handler is called, this is undefined. If you look at the call stack, you see that executeDispatch calls invokeGuardedCallbackAndCatchFirstError with an explicit value of undefined for the context object that is ultimately the value of this inside the callback. React and Babel try to hide all this from you when you are writing code, but they cannot completely hide this from the debugger, particularly with respect to this, so in this case you have to go to the actual code to see that you need to refer to _this in the debugger.






    share|improve this answer















    I created an example on CodeSandbox that I think reproduces your issue, though I'm not sure. Please create your own example if it does not. The relevant code is included below.



    In this example, the code works fine. console.log(this, "hello") logs a Square object + "hello" as you might expect. If you put a breakpoint on the let y = 2 + 2 line, the Chrome debugger will show



    this: undefined
    x: 2
    y: undefined


    Of course, y is undefined because the let y statement has not executed yet. x is defined, as expected. this is undefined because React and Babel are jumping through lots of hoops under the covers, and this is, in fact, undefined. If you want to access this from the debugger, you need to use _this. In fact, even though you put a breakpoint on the line let y = 2 + 2, that is not the actual source being executed or where the actual breakpoint is. What you are seeing is a convenience provided by a source map that lets you view and set a breakpoint on the code you wrote despite the fact that the actual code being run is completely different (the result of processing by Babel etc.).



    The code I wrote is:



    class Square extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    value: null
    };
    }

    click = () => {
    console.log(this, "hello");
    let x = 1 + 1; //This is just here to let chrome put a break point here.
    let y = 2 + 2; //This is just here to let chrome put a break point here.
    };

    render() {
    return (
    <button className="square" onClick={this.click}>
    {this.props.value}
    </button>
    );
    }
    }


    the code actually running is:



    var Square =
    /*#__PURE__*/
    function (_React$Component) {
    (0, _inherits2.default)(Square, _React$Component);

    function Square(props) {
    var _this;

    (0, _classCallCheck2.default)(this, Square);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Square).call(this, props));
    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "click", function () {
    console.log((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "hello");
    var x = 1 + 1; //This is just here to let chrome put a break point here.

    var y = 2 + 2; //This is just here to let chrome put a break point here.
    });
    _this.state = {
    value: null
    };
    return _this;
    }

    (0, _createClass2.default)(Square, [{
    key: "render",
    value: function render() {
    return _react.default.createElement("button", {
    className: "square",
    onClick: this.click
    }, this.props.value);
    }
    }]);
    return Square;
    }(_react.default.Component);


    Because of the React.js internals (in particular, the way it wraps events), by the time the handler is called, this is undefined. If you look at the call stack, you see that executeDispatch calls invokeGuardedCallbackAndCatchFirstError with an explicit value of undefined for the context object that is ultimately the value of this inside the callback. React and Babel try to hide all this from you when you are writing code, but they cannot completely hide this from the debugger, particularly with respect to this, so in this case you have to go to the actual code to see that you need to refer to _this in the debugger.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 10 '18 at 13:43

























    answered Dec 2 '18 at 2:24









    Old ProOld Pro

    15.2k23970




    15.2k23970













    • Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

      – dwjohnston
      Dec 9 '18 at 23:25











    • This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

      – dwjohnston
      Dec 10 '18 at 6:20













    • @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

      – Old Pro
      Dec 12 '18 at 21:44











    • Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

      – dwjohnston
      Dec 12 '18 at 23:24











    • @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

      – Old Pro
      Dec 13 '18 at 5:14



















    • Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

      – dwjohnston
      Dec 9 '18 at 23:25











    • This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

      – dwjohnston
      Dec 10 '18 at 6:20













    • @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

      – Old Pro
      Dec 12 '18 at 21:44











    • Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

      – dwjohnston
      Dec 12 '18 at 23:24











    • @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

      – Old Pro
      Dec 13 '18 at 5:14

















    Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

    – dwjohnston
    Dec 9 '18 at 23:25





    Unfortunately I've run out of time to award the bounty before testing this answer. Will report back when I have done so.

    – dwjohnston
    Dec 9 '18 at 23:25













    This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

    – dwjohnston
    Dec 10 '18 at 6:20







    This makes makes this be undefined - which isn't what I want - I want to refer to the React class instance.

    – dwjohnston
    Dec 10 '18 at 6:20















    @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

    – Old Pro
    Dec 12 '18 at 21:44





    @dwjohnston I replaced the previous answer with a new one now that I have a different understanding of your question. Please accept this answer if it does, in fact, answer your question.

    – Old Pro
    Dec 12 '18 at 21:44













    Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

    – dwjohnston
    Dec 12 '18 at 23:24





    Thanks - I appreciate the effort you've gone to. Your example is what I'm trying to achieve (What it really is in the real world, pausing the thread and inspecting the state at a given time). It seems like the only way is to use the manual binding method - though I do have an idea that I'll post as an answer.

    – dwjohnston
    Dec 12 '18 at 23:24













    @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

    – Old Pro
    Dec 13 '18 at 5:14





    @dwjohnston I don't understand what your issue is with this solution. You can just add _this (or _this.props and/or _this.state or even this || _this) as a watch expression or type it in the console to examine the component.

    – Old Pro
    Dec 13 '18 at 5:14













    0














    I think you need to set babel options to disable module processing. See this answer:



    How to stop babel from transpiling 'this' to 'undefined'



    In your .babelrc:



    {
    "presets": [
    [ "es2015", { "modules": false } ]
    ]
    }





    share|improve this answer
























    • Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

      – dwjohnston
      Dec 10 '18 at 6:21
















    0














    I think you need to set babel options to disable module processing. See this answer:



    How to stop babel from transpiling 'this' to 'undefined'



    In your .babelrc:



    {
    "presets": [
    [ "es2015", { "modules": false } ]
    ]
    }





    share|improve this answer
























    • Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

      – dwjohnston
      Dec 10 '18 at 6:21














    0












    0








    0







    I think you need to set babel options to disable module processing. See this answer:



    How to stop babel from transpiling 'this' to 'undefined'



    In your .babelrc:



    {
    "presets": [
    [ "es2015", { "modules": false } ]
    ]
    }





    share|improve this answer













    I think you need to set babel options to disable module processing. See this answer:



    How to stop babel from transpiling 'this' to 'undefined'



    In your .babelrc:



    {
    "presets": [
    [ "es2015", { "modules": false } ]
    ]
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 6 '18 at 23:11









    Tiago CoelhoTiago Coelho

    1,064512




    1,064512













    • Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

      – dwjohnston
      Dec 10 '18 at 6:21



















    • Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

      – dwjohnston
      Dec 10 '18 at 6:21

















    Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

    – dwjohnston
    Dec 10 '18 at 6:21





    Note that I'm using create-react-app - I'll be getting way into the weeds with this solution.

    – dwjohnston
    Dec 10 '18 at 6:21











    0














    An pragmatic alternative - if what you're wanting to do is inspect the state/props of a react component at a certain point, is to enter the break point as per normal - but instead of using the debugger to inspect the state - use the react dev tools plugin to actually examine the state.



    This might prove to be a bit fiddly, but it's an option.






    share|improve this answer




























      0














      An pragmatic alternative - if what you're wanting to do is inspect the state/props of a react component at a certain point, is to enter the break point as per normal - but instead of using the debugger to inspect the state - use the react dev tools plugin to actually examine the state.



      This might prove to be a bit fiddly, but it's an option.






      share|improve this answer


























        0












        0








        0







        An pragmatic alternative - if what you're wanting to do is inspect the state/props of a react component at a certain point, is to enter the break point as per normal - but instead of using the debugger to inspect the state - use the react dev tools plugin to actually examine the state.



        This might prove to be a bit fiddly, but it's an option.






        share|improve this answer













        An pragmatic alternative - if what you're wanting to do is inspect the state/props of a react component at a certain point, is to enter the break point as per normal - but instead of using the debugger to inspect the state - use the react dev tools plugin to actually examine the state.



        This might prove to be a bit fiddly, but it's an option.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 12 '18 at 23:26









        dwjohnstondwjohnston

        2,907114994




        2,907114994






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53513424%2fchrome-firefox-debuggers-not-displaying-the-correct-value-for-this-in-a-react%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)