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 likefunction MyComponent(props) {
/* do stuff with props.prop1 and props.prop2 */
}
you can instead writefunction 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 ?