0

I'm probably asking the wrong question, but I'd like to be able to execute a parent function when called from a child function, not an event.

I have more or the less the following setup: Declaring the _foo method in the parent and passing it on down to ChildTwo, where executing it via an onClick event handler works as expected. However, I ran into a situation where I need to call the _foo method manually from inside another method (I've simplified it here, but it will be called conditionally).

My question is what do I need to do to call the _foo method from _bar() ?

Thanks in advance!

export defaultclass Parent extends Component {
  constructor() {
    super();
  }

  _foo() {
    alert('alert!');
  }

  render() { <ChildOne _foo={this._foo.bind(this)} /> }
}

const ChildOne = (props) => {
  const { _foo } = props;
  return ( <ChildTwo _foo={_foo} /> );
}

export default class ChildTwo extends Component {
  constructor(props) {
    super(props);
    this._foo = this.props._foo.bind(this);
  }

  _bar() {
    //this._foo.call();
    //this._foo();
    //what do I do here?
  }

  render() {
      return (
        <div>
          <button onClick={this._foo}> Works! </button>
          <button onClick={this._bar}>Doesnt Work!</button>
        </div>
      );
  }
};

3
  • This shouldn't work: <button onClick={this._foo}> Works! </button> or at least shouldn't really do anything, since this._foo is undefined. I'm assuming it's just a typo in the example, so could you perhaps check your snippet again, to see if it matches your original code, and fix any typos? Commented Dec 23, 2016 at 1:57
  • @NikolajDamLarsen ah yes, thank you! 'Tis fixed. Commented Dec 23, 2016 at 1:59
  • 1
    When using a function within a component as a callback, you have to bind the callback function to the component, otherwise using this in the function body would reference the wrong object. So in your ChildTwo-component, you should add this line to your constructor: this._bar = this._bar.bind(this). Then you can go ahead and call this._foo(); in the body of _bar. Commented Dec 23, 2016 at 3:06

1 Answer 1

1

If you really want to do this, then I would solve it by passing the child component as an argument to the method that is still bound to the original parent.

For example:

export defaultclass Parent extends Component {
  constructor() {
    super();
    this._foo = this._foo.bind(this)
  }

  _foo(childComponent) {
    alert({ parent: this, child: childComponent });
  }

  render() { <ChildOne _foo={this._foo} /> }
}

const ChildOne = (props) => {
  const { _foo } = props;
  return ( <ChildTwo _foo={_foo} /> );
}

export default class ChildTwo extends Component {
  constructor(props) {
    super(props);
    this._bar = this._bar.bind(this);
  }

  _bar() {
    const { _foo } = this.props;

    // Passing a reference to self as argument
    _foo(this);
  }

  render() {
      return (
        <div>
          <button onClick={this._bar}>Should Work Now!</button>
        </div>
      );
  }
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.