无法将反跳分配给类属性

时间:2018-06-28 19:05:23

标签: javascript reactjs ecmascript-6 lodash debounce

我正在使用带有第2阶段预设的Babel,并具有类似这样的React组件类:

class Test extends Component {
  someValue = 'Hello';

  componentDidMount() {
    this.debouncedHandleResize = debounce(this.handleResize, 1000);
    window.addEventListener('resize', this.debouncedHandleResize);
  }

  handleResize = () => {
    console.log(this.someValue);
  }
}

这按预期工作。窗口调整大小后1000ms,将触发handleResize方法,并且控制台记录“ Hello”。

为什么我不能执行以下操作?

class Test extends Component {
  someValue = 'Hello';

  debouncedHandleResize = debounce(this.handleResize, 1000);

  componentDidMount() {
    window.addEventListener('resize', this.debouncedHandleResize);
  }

  handleResize = () => {
    console.log(this.someValue);
  }
}

在这种情况下,我会收到错误消息:

TypeError: Expected a function

我肯定会丢失一些东西,但是我认为这两种方法基本上都是为类分配属性值的方法。

3 个答案:

答案 0 :(得分:3)

由于您已经更新了代码:问题是debouncedHandleResizehandleResize都是公共类字段。由于debouncedHandleResize分配是第一位的,因此您试图在handleResize存在之前对其进行引用。

公共类字段是按顺序求值的,所以

class Test {
  debouncedHandleResize = debounce(this.handleResize, 1000);

  handleResize = () => {
    console.log(this.someValue);
  }
}

等同于

class Test {
  constructor() {
    this.debouncedHandleResize = debounce(this.handleResize, 1000);

    this.handleResize = () => {
      console.log(this.someValue);
    }
}

很明显为什么这行不通。

解决方案

更改分配顺序:

class Test {
  handleResize = () => {
    console.log(this.someValue);
  }
  debouncedHandleResize = debounce(this.handleResize, 1000);
}

答案 1 :(得分:1)

也许应该是:

class Test extends React.Component {
    ...
}

答案 2 :(得分:0)

我发现了问题所在。在我的第二个示例(抛出错误的示例)中,class属性设置如下:

debouncedHandleResize = debounce(this.handleResize, 1000);

由于某种原因,该错误抱怨它不喜欢this.handleResize并说它不是一个函数。尽管我不是100%理解这一点,但通过手动传递函数的简单测试却消除了错误:

debouncedHandleResize = debounce(() => false, 1000);

有了这些知识,我编写班级的新成功方法是:

class Test extends Component {
  someValue = 'Hello';

  componentDidMount() {
    window.addEventListener('resize', this.handleResize);
  }

  handleResize = debounce(() => console.log(this.someValue), 1000)
}