I'm working with d3 (v3)'s brush feature right now and ran into a situation where binding in the constructor works, but using a class function doesn't. My .babelrc
is set up for class functions with "presets": ["flow", "latest", "stage-2", "react"]
and I've gotten arrow functions working in the rest of the code, so it's not a matter of transpilers.
Code in question:
this.brush = d3.svg.brush()
.x(xScale)
.on("brushend", this.changeDates)
const brushGroup = d3.select(this.node).append("g")
.attr("class", "brush")
.call(brush)
If I bind change dates in the constructor as follows, I find that this
in the function changeDates
is the React Component ExampleSVG
, which is the desired behavior.
class ExampleSVG extends Component {
constructor(props) {
super(props)
this.changeDates = this.changeDates.bind(this)
}
changeDates() {
console.log(this) //ExampleSVG {props: {...}, context: {...}}
}
...d3 stuff
}
However, if I try binding via the arrow function, this
becomes the function svg group.
class Example extends Component {
changeDates = () => {
console.log(this) //<g class="brush" ... />
}
...d3 stuff
}
Why is the arrow function not binding (once again, not a transpilation issue, I have plenty of binding arrows in my code)? There's probably something about d3/this that I'm missing here, but I want to figure this out! Is it call
? In which case, what does call
do such that it can override arrow binding?