React子回调绑定此而不覆盖原始this

问题描述 投票:4回答:2
class Parent extends React.Component {

  constructor(props) {
    super(props)
    this.handleChildOnClick = this.handleChildOnClick.bind(this)
  }

  handleChildOnClick() {
    /* I would like to do something here that requires both Child and Parent.
     * But 'this' points to Parent because I binded it in Parent's constructor.
     */
  }

  render() {
    return(
    <Child
      onClick={this.handleChildOnClick}
    />)
  }

}

handleChildOnClick回调中,我想调用Child的方法来检索一些数据并相应地更新Parent的状态。

如果我在Parent构造函数中将Parent的this绑定到handleChildOnClick,那么我将失去对Child的引用,因此无法调用Child的方法。但是如果我不绑定它,那么我就无法在handleChildOnClick中设置Parent的状态。

有没有办法绑定this而不是覆盖原来的this

编辑: 我的子组件来自库,所以我无法修改它。

编辑: 我正在使用react-google-maps库。子组件是GoogleMap,每当GoogleMap的getBounds()回调被触发时,我想在Parent的状态下存储GoogleMap的新视图边界(通过在GoogleMap上调用onBoundsChange)。

javascript reactjs this
2个回答
2
投票

所需的this不被视为Child背景。该函数作为回调传递,它提供了一些动态this。如果thisChild组件实例,那只是巧合。

该问题特定于遗留或设计不良的库,它们不包含现代JS OOP并依赖于任意动态this而不是将所有必要数据作为函数参数传递。一个着名的例子是D3库。

一个功能不能有两个this。一个流行的解决方法是self = this技巧与常规(非箭头)功能相结合。但是,这对于类语法来说变得笨拙,因为它不能放在constructor之外:

class Parent extends React.Component {
  constructor(props) {
    super(props)

    const self = this;
    this.handleChildOnClick = function handleChildOnClick() {
      // `self` is Parent instance
      // `this` is dynamic context
    };
  }

  render() {
    return(
    <Child
      onClick={this.handleChildOnClick}
    />)
  }
}

这种重新洗牌很不方便,因为this通常被认为是JS OOP中的类实例。

正如this related answer中所解释的,解决此问题的一种方法是提供辅助函数,在内部执行此技巧并将动态上下文映射到函数参数:

function contextWrapper(fn) {
    const self = this;

    return function (...args) {
        return fn.call(self, this, ...args);
    }
}

class Parent extends React.Component {
  constructor(props) {
    super(props)

    this.handleChildOnClick = contextWrapper(this.handleChildOnClick.bind(this));
  }

  handleChildOnClick(context) {
      // `this` is Parent instance
      // `context` parameter is dynamic context
    }
  }

  render() {
    return(
    <Child
      onClick={this.handleChildOnClick}
    />)
  }
}

2
投票

您需要从其props中调用子组件中的处理程序并更新父级的状态:

class Parent extends React.Component {

  handleChildOnClick = (data) => {
    /* I would like to do something here that requires both Child and Parent.
     * But 'this' points to Parent because I binded it in Parent's constructor.
     */
  }

  render() {
    return(
    <Child
      handleChildOnClick={this.handleChildOnClick}
    />)
  }

}

然后在你的子组件中:

class Child extends React.Component {

      handleChildOnClick = () => {
        // you can even send data to parent click handler
        this.props.handleChildOnClick(data); // pass any arguments 
      }

      render() {
        return(
        <button
          onClick={this.handleChildOnClick}
        />)
      }

    }

这就是它在单向绑定中起作用的方式。我希望这会有所帮助

© www.soinside.com 2019 - 2024. All rights reserved.