Mobx - React: reacting to an observable property on a child component ref causing infinite recursion

964 Views Asked by At

So I have the following setup (that is probably not the best approach, but bear with me):

@observer class ParentComponent extends Component {
  @observable.ref childComponent

  render() {
    return (<div>
      <ChildComponent ref={(ref)=> this.childComponent=ref}/>

      <button disabled={this.childComponent && this.childComponent.isBusy}/>
    </div>)
  }
}

@observer class ChildComponent extends Component {
  @observable isBusy = false

  // called at some point after render in response to a user action
  handleBusy() {this.isBusy = true} 

  render() {…}
}

This is causing RangeError: Maximum call stack size exceeded errors, and it more or less makes sense that this causes recursion, because an observable is getting set while rending, which triggers a render, causing the observable to be set, etc. (However I don't quite get how this is infinitely recursive. it seems like it would be stable within a couple loops).

I know this is probably an anti-pattern, but is there anyway to get this to work?

1

There are 1 best solutions below

0
On

You are better off putting the shared state in the parent component instead.

Example (JSBin)

@observer 
class ParentComponent extends Component {
  @observable isBusy = false;

  handleBusy = () => {
    this.isBusy = true;
  }

  render() {
    const { isBusy, handleBusy } = this;
    return <div>
      <ChildComponent onClick={handleBusy}/>
      <button disabled={isBusy}> Parent Button </button>
    </div>;
  }
}

@observer 
class ChildComponent extends Component {
  render() {
    const { onClick } = this.props;
    return <div>
      <button onClick={onClick}> Child Button </button>
    </div>;
  }
}