I have this code. I imported some ponents from Semantic UI.
import React from 'react'
import { Card, Image, Grid } from 'semantic-ui-react'
I am trying to call function when error (404) appears when loading image.
export default class HotelCards extends React.Component {
// constructor
constructor(props){
super(props)
this.handleError = this.handleError.bind(this);
}
// state
state = {}
This is the function I'd like to call: (not that if I log this
inside render function I get instance of current class)
handleError() {
console.log(this);
}
render() {
if (!this.props.hotels) return null;
return (
<Grid doubling stackable columns="4" className="cards-container">
{
this.props.hotels.map(function(e, i) {
return (
<Grid.Column key={i} className="card-column">
<Card>
From this element:
<Image src={e.hotel.image} onError={this.handleError} />
</Card>
</Grid.Column>
)
})
}
</Grid>
);
}//render
}//class
However I get error that this
is undefined
.
TypeError: this is undefined
Stack trace:
render/<@http://localhost:1337/app/bundle.js:63883:92
...
In vanilla JavaScript my approach for this would be
<img src="image.png" onError="this.onerror=null;this.src='/placeholder.jpg';" />
How do I bind this function to ponent properly?
I have this code. I imported some ponents from Semantic UI.
import React from 'react'
import { Card, Image, Grid } from 'semantic-ui-react'
I am trying to call function when error (404) appears when loading image.
export default class HotelCards extends React.Component {
// constructor
constructor(props){
super(props)
this.handleError = this.handleError.bind(this);
}
// state
state = {}
This is the function I'd like to call: (not that if I log this
inside render function I get instance of current class)
handleError() {
console.log(this);
}
render() {
if (!this.props.hotels) return null;
return (
<Grid doubling stackable columns="4" className="cards-container">
{
this.props.hotels.map(function(e, i) {
return (
<Grid.Column key={i} className="card-column">
<Card>
From this element:
<Image src={e.hotel.image} onError={this.handleError} />
</Card>
</Grid.Column>
)
})
}
</Grid>
);
}//render
}//class
However I get error that this
is undefined
.
TypeError: this is undefined
Stack trace:
render/<@http://localhost:1337/app/bundle.js:63883:92
...
In vanilla JavaScript my approach for this would be
<img src="image.png" onError="this.onerror=null;this.src='/placeholder.jpg';" />
How do I bind this function to ponent properly?
Share Improve this question edited Dec 27, 2016 at 11:14 Kunok asked Dec 27, 2016 at 11:06 KunokKunok 8,8099 gold badges52 silver badges93 bronze badges 1-
1
I've just noticed that you're not passing arrow function to
map
, so the current value ofthis
is lost! – Tomasz Lenarcik Commented Dec 27, 2016 at 11:21
5 Answers
Reset to default 3The typical approach is using the so called "late binding", i.e.
constructor() {
// ...
this.handleError = this.handleError.bind(this);
}
handleError() {
console.log('THIS', this);
}
The reason your code did not work was because your fat arrow is binding to the context in which your class is being defined.
Alternatively, you could also bind at the rendering level as suggested in another answer, so:
<Image src={e.hotel.image} onError={this.handleError.bind(this)} />
However, the problem with that solution is that it produces a new handler function on every call to your render
method, which can (but don't have to) negatively influence your rendering performance if you're using some kind of property equality testing optimization techniques.
Ok guys, I found the reason why this
is undefined
.
It is because these stuff happen inside .map
method, so I had to bind this
to it like this:
this.props.hotels.map(function(e, i) {
...
}, this)
or as @apendua mented, by using arrow function so this
doesn't get lost:
this.props.hotels.map((e, i) => {
...
})
Fat arrow functions as methods in a class are not supported in ES6, so you'd first have to define handError as method like this:
handleError() {
console.log('test');
}
and you should be able to bind to it so it can use this if required:
<Image src={e.hotel.image} onError={this.handleError.bind(this} />
To void the bind in your render function (which in some case can have performance) you can do the binding in your constructor function:
this.handleError = this.handleError.bind(this);
@kunok : nice you found your answer. Arrow function ( => ) keep the this context same as enclosing function.
Add this.state is inside ponent the constructor.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744441588a4574385.html
评论列表(0条)