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
.
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>
)
}
}
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>
)
}
}
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 }))
}
}
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:
- I ❤ Ramda - Partial Application with a Special Placeholder
- Functional Programming: Alternatives to the IF #Functional #JavaScript #Functors
- Keep your code dumb
#nothis