d3回调+ React

时间:2018-06-20 01:14:31

标签: javascript reactjs d3.js

我现在正在使用d3(v3)的笔刷功能,遇到了构造函数中的绑定有效但使用类函数无效的情况。我的.babelrc是为"presets": ["flow", "latest", "stage-2", "react"]的类函数设置的,而我的其余代码中都使用了箭头函数,所以这与编译器无关。

有问题的代码:

    this.brush = d3.svg.brush()
        .x(xScale)
        .on("brushend", this.changeDates)

    const brushGroup = d3.select(this.node).append("g")
        .attr("class", "brush")
        .call(brush)

如果按如下方式在构造函数中绑定更改日期,则会发现函数this中的changeDates是React组件ExampleSVG,这是所需的行为。

class ExampleSVG extends Component {
    constructor(props) {
        super(props)
        this.changeDates = this.changeDates.bind(this)
    }   

    changeDates() {
        console.log(this) //ExampleSVG {props: {...}, context: {...}}
    }

    ...d3 stuff
}

但是,如果我尝试通过箭头函数进行绑定,则this会成为函数svg组。

class Example extends Component {
    changeDates = () => {
        console.log(this) //<g class="brush" ... />
    }

    ...d3 stuff
}

为什么arrow函数没有绑定(再一次,不是翻译问题,我的代码中有很多绑定箭头)?我在这里可能缺少有关d3 / this的某些信息,但我想弄清楚!是call吗?在这种情况下,call可以做什么以使其可以覆盖箭头绑定?

1 个答案:

答案 0 :(得分:3)

箭头功能没有自己的this

通过将非箭头函数传递给D3选择方法(例如.attr().on()),D3使用function.apply()将this设置为要修改的元素,这就是为什么它不是窗口的原因(全局作用域this;如果不是,则为this,其作用域包括箭头功能)。

但是,由于箭头函数不能具有自己的作用域this,因此this指的是this具有包含箭头函数的作用域的任何对象。

因此,this的典型功能与箭头功能相比有所不同。因此,为什么不应该在要求您选择this的d3选择方法中不使用粗箭头功能,除非您使用其他方法来选择该元素。

来自MDN

  

在箭头函数中,this保留了封闭的词法上下文this的值。在全局代码中,它将被设置为全局对象...这同样适用于在其他函数内部创建的箭头函数:它们仍然属于封闭的词法上下文。


但是,您肯定可以保留箭头功能,并且仍然引用将为this的元素,因为第二个参数是当前索引,第三个参数是所选内容中的元素数组。这个answer已经说过这种方法。