Creating React components without this. #nothis

JavaScript Joel - Aug 14 '18 - - Dev Community

Change

Easily create React components that are completely devoid of this.

You might remember me as the psychopath who wrote Rethinking JavaScript: The complete elimination and eradication of JavaScript's this

Well, I'm back and this time I've got a new React Component for you!

But WHY, you ask angrily?

I subscribe to the Douglas Crockford way of thinking.

"There are a few (features) we know that are going to be bad. The worst is Class. Class was the most requested new feature in JavaScript. And all of the requests came from Java programmers who have to program in JavaScript and don't want to learn how to do that. So they wanted something that looks like Java so they could be more comfortable. Those people will go to their graves not knowing how misserable they are." - Douglas Crockford

And in the same way that Douglas Crockford found his programs improved when he stopped using this, I found this to be true in my code as well.

"I was very surprised to discover that my programs got better. It was not a hardship to not use this. It was actually a benefit. My programs got smaller and easier and you know, that's what we're all looking for" -- Douglas Crockford

Even so, I do understand that there is little chance of me changing your mind because...

"Programmers are as emotional and irrational as normal people. So when the solution finally arrives, most of us will reject it." -- Douglas Crockford

This isn't just some anecdotal statement. Crockford goes on to provide real world examples, such as...

"It took a generation to agree that GOTO was a bad idea. We argued passionately, emotionally for 2 decades about whether we should use GOTO or not." -- Douglas Crockford

Well, this is the GOTO of JavaScript and I understand that it's not going to go away overnight. But I would like to hope that it won't take us two decades like GOTO.

Doctor is hurts when i .this

What does this all mean for React Components?

React does have a functional component, but React's most popular way of creating components is to create a class and extend from React.Component and a Class comes with this.

Then I asked myself, what if I could use React.Component but without this. And that is how NoThis.Component was born.

You'll notice NoThis.Component is used in a way familiar to React.Component. The context you would previously access via this is available as the first function argument.

import React from 'react'
import NoThis from 'nothis-react'

class Counter extends NoThis.Component {
  state = { count: 0 }

  increment(ctx) {
    ctx.setState(state => ({ count: state.count + 1 }))
  }

  render(ctx) {
    return (
      <div>
        <button onClick={ctx.increment}>{ctx.state.count}</button>
      </div>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

increment and render have become pure functions, acting only on their inputs!

Argument Destructuring

If you love destructuring as much as I do, then code like this now becomes possible!

import React from 'react'
import NoThis from 'nothis-react'

class Counter extends NoThis.Component {
  state = { count: 0 }

  increment({ setState }) {
    setState(({ count }) => ({ count: count + 1 }))
  }

  render({ increment, state: { count } }) {
    return (
      <div>
        <button onClick={increment}>{count}</button>
      </div>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

Now that is some sexy code.

Excluding Functions

A function can be excluded from nothis by writing it as a class property.

class Counter extends NoThis.Component {
  increment = () => {
    this.setState(({ count }) => ({ count: count + 1 }))
  }
}
Enter fullscreen mode Exit fullscreen mode

Wrapup

This is some experimental future code, so treat it as such. Please do play with it and report any bugs or request features at the Github repo.

Join the #nothis movement and hit me up on the tweety.

If you hated this article, you might also hate these too:

#nothis

Cheers!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .