【问题标题】:How to force React ES6 static method's "this" to be bound to lexical scope如何强制 React ES6 静态方法的“this”绑定到词法范围
【发布时间】:2015-09-28 14:40:50
【问题描述】:

在 React(通过 babel 使用 ES6)中,我试图创建一个静态方法来更新它所包含的组件的状态。将对象作为参数。问题是“this”永远不会绑定到词法范围。

static updateList = (Item) => {
    this.setState({ cartUpdated: Date.now() }); //setState is not available
}

在其他组件中...

<div onClick={Cart.updateList.bind(this,this.props)}>Click</div>

起初我认为这可能是由于通过“bind”传递的“this”,但我在包含点击处理程序的组件中创建了一个重复的非静态箭头方法,我可以很好地访问词法“this”。

在绝望中也尝试制作 setState 的静态克隆,但没有成功。

我认为这是一个结构/安全决定(如果我们泄露“this”,我们就会泄露所有内容!)但是如何处理对“this”的访问?此限制是否强制 updateList 函数必须位于 updateList 和带有单击处理程序的组件之上?当然,这实际上可能更像反应,但我很好奇。

【问题讨论】:

  • 一个更新它所包含的组件状态的静态方法” - 你没有任何意义。静态方法在类上,没有状态。你想要一个实例方法吗?然后使用一个。
  • 如果您可以提供一个可以通过实例访问的方法的工作示例,当在调用组件的子组件或父组件中找不到该实例时,那就太棒了。跨度>
  • 找不到所述实例时”是什么意思?我假设this 是你的实例?
  • 我的意思是我试图从中访问方法的 React 组件。据我所知,除非我渲染组件并通过 refs 访问它的方法、扩展它或继承方法作为 props,否则我无法直接访问它的方法。
  • 例如,如果我这样做了: var Child = React.createClass({…}); var myChild = React.render(React.createElement(Child, {}), mountNode); myChild.someMethod();

标签: javascript reactjs ecmascript-6 arrow-functions


【解决方案1】:

ES6 static 关键字仅适用于类的方法,不适用于标准属性。因此,您尝试的分配在语法上无效。必须写:

static updateList(Item) {
    this.setState({ cartUpdated: Date.now() }); //setState is not available
}

请参阅MDN 的文档以获得更清晰的解释。

【讨论】:

  • setState 不也是一个实例方法吗?即使您将静态方法重新绑定到其他东西,它也不应该是静态的。
  • 谢谢。我用箭头和非箭头功能都试过了。我相信我理解其中的区别 (=),但它并不能解决我的问题。
  • @Bergi 你是对的。我只是单纯地用 ES6 术语思考。
【解决方案2】:

class StaticClass extends React.Component{
  static updateList(item) {
    this.setState({
      alert: Date.now()
    });
  }
}

class Cpn extends React.Component{
  constructor() {
    super();
    this.state = {};
  }
  
  render() {
    if (this.state.alert) {
      alert(this.state.alert);
    }
    
    return (
      <div onClick={StaticClass.updateList.bind(this, this.props)}>
        Click
      </div>
    );
  }
}

ReactDOM.render(
  <Cpn prop1="1" prop2="2"/>,
  document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

似乎工作正常。好吧,也许 2015 年的情况有所不同?或者我可能误解了这个问题?无论如何,我的测试代码似乎运行良好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 2015-11-18
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    相关资源
    最近更新 更多