反应子回调与此绑定,而不会覆盖原始的this

时间:2018-09-01 07:36:55

标签: javascript reactjs this

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的状态。

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

有没有办法绑定this而不覆盖原始的this吗?

编辑:
我的孩子组件来自图书馆,所以我无法对其进行修改。

编辑:
我正在使用react-google-maps库。子组件是GoogleMap,每当触发GoogleMap的getBounds()回调函数时,我都想以Parent的状态(通过在GoogleMap上调用onBoundsChange)存储GoogleMap的新视图范围。 / p>

2 个答案:

答案 0 :(得分: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}
        />)
      }

    }

这就是它在React的PNE方式绑定中的工作方式。 我希望这会有所帮助

答案 1 :(得分: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}
    />)
  }
}