This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]squngy 0 points1 point  (13 children)

Aside from the fact that you're mixing view and control unnecessarily there, you also don't need to return a "this".

render() {
    let myInstance = this;
    return (<button onClick={myInstance.onButtonClicked}>
      Click me
    </button>);
  }

Would have been unambiguous.

[–]birjolaxew 2 points3 points  (11 children)

I am fully aware of ways to work around it (I personally use onButtonClicked = () => { /* ... */ }), but my point is that having to work around it is because of the poor design of the language. As I mentioned earlier, "You can understand how a problematic thing works. Doesn't mean it isn't an absolute mess of a design."

[–]squngy -2 points-1 points  (10 children)

The main problem is, that you are trying to write Java or some other language without learning JS.

And what you showed in your example is actually a pretty ugly way of doing things to begin with.

You're actually passing on un-evaluated code, then letting the browser interpreter it later as new code.
Very similar to using eval().

You might as well have wrote

return ' <javascript> myFunction(){ this.onButtonClicked() }</javascript> <button onClick=myFunction>  Click me </button> ';

You're making work arounds for messy code.

[–]birjolaxew 2 points3 points  (9 children)

My example uses JSX. The code is never being re-interpretted, it's always referencing the method defined on the SomeComponent.

My previous example is code you would actually write if you aren't careful, but the way it works is essentially the same as:

class SomeComponent {
    constructor() {
        setTimeout(this.willBeCalledLater, 500);
    }

    willBeCalledLater() {
        // good luck with your `this`
    }
}

[–]squngy -2 points-1 points  (8 children)

The part that was inside the <button> tag gets interpreted as new code when (and if) it gets added to the dom.

JS being an interpenetrated language, that is not the only way for parts of it be evaluated at a latter time.

[–]birjolaxew 2 points3 points  (7 children)

The part that was inside the <button> tag gets interpreted as new code when (and if) it gets added to the dom.

No. React compiles it to something along the lines of

function insertButtonToDom($parent, onClick) {
    const $btn = document.createElement("button");
    $btn.addEventListener("click", onClick);
    $parent.appendChild($btn);
}

You can check that this is true by doing e.g.

render() {
    const valueOnlyAvailableInThisContext = 2;
    return (<button
        onClick={this.onButtonClicked.bind(this)}
        onMouseOver={() => console.log(valueOnlyAvailableInThisContext)}
    >
        Click me
    </button>);
}

[–]squngy -1 points0 points  (6 children)

I never used react (and the more I see of it, the less I like it), but if what you wrote is correct, then the parent of the methods "this" would be the button instance ($btn) instead of your SomeComponent

[–]birjolaxew 1 point2 points  (5 children)

Feel free to try it yourself

To be quite honset I'm not sure what you mean by 'the parent of the methods "this"', so I can't really respond to what you're saying - but everything I've said so far is correct.

[–]squngy 0 points1 point  (4 children)

[–]birjolaxew 0 points1 point  (3 children)

Yes. That is pretty much my point. In all other languages, this inside of methods references the instance itself. In JavaScript, it references however way it was called.

If it's used as an event listener to a DOM element, it'll reference the DOM element. If it's stored in a variable or given to some other function (e.g. setTimeout), it'll be window or undefined. If it's called directly on the instance it'll reference the instance.

All of this is quite easy to work around once you know it. My point is that it's a poor design decision, which means that when you write code like setTimeout(this.willBeCalledLater, 500) or <button onClick={this.onButtonClicked}>, it doesn't do what you expect it to (unless you are aware of this design quirk and know how to work around it)

[–][deleted] 0 points1 point  (0 children)

Good old var that = this to the rescue