Confused about "this" and "bind" in react, please guide

So, i am trying to do some example in react and below is one where i try and fetch popular repositories in github, i can understand and even write the code , but the biggest confusion is the random nature of use of bind and this keyword, why and where to use them is still something baffles me, most books and videos do not explain it …

Can some one guide me to some resource or tell me about it, why to use “this” and where to use it , why to use “bind” and where to use it, why not use it every where and at some places only …Thanks



import React from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
var api = require('../utils/api');

function SelectedLanguage(props) {
    var languages = ['All', 'Ruby', 'Python', 'JavaScript', '.NET'];
    return (
        <ul className="languages">

            {
                languages.map((lang) => {
                    return <li
                        style={lang === props.selectedLanguage ? { color: '#d0021b' } : null}
                        onClick={props.onClick.bind(null, lang)}
                        key={lang}> {lang} </li>

                })

            }
        </ul>
    )
}



class Popular extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedLanguage: "All"
        }
        this.updateLanguage = this.updateLanguage.bind(this);
    }

    updateLanguage(lang) {
        this.setState(function () {
            return {
                selectedLanguage: lang,
                repos: null
            }
        })
        api.fetchPopularRepos(lang)
        .then(function(repos){
            this.setState(function(){
                return {
                    repos: repos
                }
            })
        }.bind(this))

    }

    componentDidMount() {
           this.updateLanguage(this.state.selectedLanguage);
    }


    render() {

        return (
            <SelectedLanguage
                selectedLanguage={this.state.selectedLanguage}
                onClick={this.updateLanguage}
            />
        )


    }
}

SelectedLanguage.propTypes = {
    onClick: PropTypes.func.isRequired,
    selectedLanguage: PropTypes.string.isRequired
}


module.exports = Popular;

@DanCooper explained ‘this’ greatly.

https://forum.freecodecamp.org/t/this-not-working-inside-the-function-kindly-guide/?source_topic_id=178771

But if that’s not enough

Bind lets you set the value of ‘this’ when the function is later called. That’s why you see it being used with events a lot. Translation : "I don’t know when this function will fire off, but when it does, call it with ‘this’.
Call and apply invokes the function RIGHT NOW, IMMEDIATELY with the set value of ‘this’

In summary, when you want to set the value of ‘this’, use call, apply , and bind

Edit: I would go and practice the examples Dan gave you because he explained it so well, that’s all you need. It’s like recursion, you just have to do it until you get it.

1 Like

can you link/post the utils/api module @amitshrivastavafcc

@DanCouper api.js , i understand the code but do not understand where to use “this” or “bind” and i see it being used extensively, so where to use it is my big confusion and some places they just use "this> some places they use bind(this)


var axios = require('axios');

module.exports = {
    fetchPopularRepos: function(languages) {
        var encodedURI = window.encodeURI('https://api.github.com/search/repositories?q=stars:>1+language:'+ languages + '&sort=stars&order=desc&type=Repositories');


        return axios.get(encodedURI)
        .then(function(response) {
            return response.data.items;
        });

    }
};

App.js


import React from 'react';
import ReactDom from 'react-dom';

var Popular = require('./Popular');


class App extends React.Component {
    render() {
        return (
            <div> 
                <Popular />
                 </div>
        ) 

        
    }
}

module.exports =  App;

https://codesandbox.io/s/mw4lrwr49

  • The callback function that gets your repos is defined in the parent but needs to be executed in the child to update the state of the parent component.
  • While you’re inside your main class (Popular), as long as you’re not doing anything untoward, this refers to that class, Popular.
  • When you pass that function to another component, that’s a whole new context: that other component has it’s own this.
  • So, to pass it around, you need to also tell the function to take the context of where it comes from with it - in this case you’re passing the handler to the SelectedLanguage component, but you want it to keep a hold of the Popular this value, because that inclues the state you’re trying to change.
  • To do that, you can do a few things, but the easiest is, in the constructor, do this.updateLanguage = this.updateLanguage.bind(this);. What you’re saying is that "every time updateLanguage is called, it should execute with the this value it uses internally bound to the instance of Popular". This means it can access Popular's state, props etc.
  • Then you can now pass that whole this.updateLanguage to the child as a prop.
  • In the child, you want that function to happen when you click. So you use React’s special onClick prop, and that takes an event handler as the value.
  • The updateLanguage function is just a function that takes a string and then updates an object (the state). onClick expects an event handler callback: an event handler is a function that takes the event that happened as the first argument. I don’t care about the details of that event, so the function just looks like () => updateLanguage(lang) - it is just a function that executes when the event happens, in this case all it does is execute updateLanguage.

A few other notes:

  • You’re mixing import syntaxes (CommonJS’ require and the native ES6’ import) - use one or the other.
  • Use const where possible, let if you need to, avoid var.
  • Use arrow functions they’re designed to help with the issues you’re having.
  • bind wraps the function in another function that keeps a hold of some context, it is useful in React because it lets you say "I want this method from Component1, but use it in Component2, but still update the state in Component1.
  • this should always refer to the class (so if you use a function for a component, you can’t use it, this is a good thing).
  • Read up on destructuring, it makes things clearer and less error-prone - e.g. props is an object, so when you have something like
    function MyComponent(props) {
      /* do stuff with props.prop1 and props.prop2 */
    }
    
    you can instead write
    function myComponent({prop1, prop2}) {
      /* now you can do stuff with prop1 and prop2 */}`
    
    It’s often clearer, and error messages tend to be more accurate

EDIT: this is quite important for testing: you’re getting too many repos. GitHub is rate-limited for public requests, which means after about four clicks, you start getting 403 errors, and you’ll have to wait [I think] a full minute before you can make more requests. This would be a good opportunity to learn caching, or to include some way to check how many clicks are being made and prevent more (with a warning to users) if you get cloise to the limit.

@DanCouper - thank you so much for your explanation , this was extremely useful and so well explained in steps …

So just one last question abt arrow function , if i use arrow function , will i not need to use bind and this etc ?