paint-brush
React — The State Bait and This Dot Problemsby@pyan
449 reads
449 reads

React — The State Bait and This Dot Problems

by Puyan WeiSeptember 6th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

ES6 updates are pretty essential to learning React, which can be quite beginner unfriendly. It is important to learn ES6, but for the sake of consistency ES6 is the way to go. Don’t mutate the original state, it is a huge no-no in functional programming. Bind Off Your ‘This’ Problems with Arrow Functions with the ‘…’ allows an existing array to be referenced but not modified. Bind off your ‘this’ function keywords to avoid scoping problems.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - React — The State Bait and This Dot Problems
Puyan Wei HackerNoon profile picture

One of the things that make React quite intimidating for new users is that there are some concepts that need to be grasped before jumping in.

Its important to learn ES6 anyways, but for the patterns and structures used its especially useful for our favourite componentized frameworks. That being said, you can still use ES5 to get it to work, but for the sake of consistency ES6 is the way to go!

Create websites with React.js!

Stop living in the past and move with the times, bruh!! :P

Don’t Mutate the State, Mate!

Most of the time this isn’t a good idea anyways, but its especially true for building front end projects. Changing the original initiated state can cause a lot of problems when things go wrong, it can make it hard to keep track of where bugs are coming from.

Here we got a shop, lets add an item…

class App extends Component { 
    constructor(props) {  
        super(props);  
            this.state = { shop:[] }; 
    }
...//
onAdd = (item) => {  
    this.state.shop.push(item);
};

To the untrained eye this is how you might think to do it. But this is a classic common situation in which we’re changing the original state which is a huge no-no in functional programming.

onAdd = (item) => { 
    let newList = this.state.shop;
    newList = newList.concat(item);
    this.setState({ shop: newList })
};

Concat is a method which combines two arrays into a new one. Here we grab the shop array (empty for now) and combine it with the item into a new array. Then we use React’s setState to modify the current state, instead of directly doing it ourselves.

onAdd = (item) => {
    let newList = this.state.shop;
    newList = [...newList, item];
    this.setState({ shop: newList })

Most of the time we use the ES6 ‘version’ of combining the arrays with the spread operator. The ‘…’ allows an existing array to be referenced but not modified, meaning we don’t mutate the original array.

Making sure that we never directly mutate the state is great practice, and we want to get in the mindset of doing that all the time.

Bind Off Your ‘This’ Problems with Arrow Functions

As you may or may not have noticed, the functions written above seem to be in a strange format. Notice there is no function keywords and for more advanced coders therefore no bind methods either.

As we pass data around in our components, we are use the

this.[function] 
to refer to functions elsewhere, but because of the lexical scope the
this
isn’t referring to where we want it to.

Arrow functions are a different way of writing functions but with the main advantage of the fact that it stops the

this
keyword from being limited to within that function.

class ParentComponent extends Component {
    render() {
        return (
            <div>
                <ChildComponent 
                parentFunction="this.parentFunction" 
                />
            </div>
        )
    };
function parentFunction() {
        console.log("Button is clicked!")
    }
}
class ChildComponent extends Component {
    render() {
        return (
            <div>
                <button onClick={this.handleClick}>
                    Click Me!
                </button>
            </div>
        )
    };
    handleClick = () => {
        this.props.parentFunction();
    }
}

Here in this child component we have a button that when clicked, uses the parentFunction props that has been passed down from the parent component.

The fact that parentFunction has been passed down using the function keyword will make the this keyword not refer to what we want if it has been written without arrow functions.

The ES5 way of solving this problem is to use the bind method but this meant every function passed down would have to be bound, and with a lot of function it would not be scaleable.

So just use [name] = () => {} to save yourself this scoping problems!

Another common scenario is when your DOM events need a parameter.

Using ES6 Arrow Functions
<button onClick={(event) => this.deleteRow(id, event)}>Delete Row</button>
// Events as parameters are explicit so can be even shorter!
<button onClick={() => this.deleteRow(id)}>Delete Row</button>
Using ES5 Bind
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

Definitely looks cleaner and needs less maintenance. We don’t have to keep track of all our binds, and therefore less prone to mistakes. Its also more readable and looks cleaner overall!

Get 2 Grips w/ES6!

If you didn’t know these concepts and jumped right in, it definitely can be quite a challenge to understand. Learning the ES6 updates are pretty essential to learning React, which can be quite beginner unfriendly.

Either way, as Javascript evolves and defies all the odds and keeps surviving onwards its becoming more apparent that it is important to keep up to date with all the new features added.

These days I try to keep things consistent by using as much ES6 syntax as possible, and Air Bnb linting. The fact that you can do so many things in different ways can be quite daunting for an aspiring newbie.

Anyways, hope that is helpful, have a great week!