Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updater seems to loose context when run through requestAnimationFrame #73

Open
qpre opened this issue Sep 26, 2016 · 1 comment
Open

Comments

@qpre
Copy link

qpre commented Sep 26, 2016

Hello,
I'm currently having an issue I can't resolve by myself.

class MyComponent {

  ...

  handleRef(ref) {
    this.rootNode = ref;

    if (ref === null) {
      cancelAnimationFrame(this.animationFrameID);
      this.animationFrameID = null;
      return;
    }

    this.onAnimationFrame();
  }

  onAnimationFrame() {
    if (!this.rootNode) { return; }

    // computes stuff

    if (conditionOnStuff) { this.setState({ field: true }); } // <-- this explodes.

    this.animationFrameID = requestAnimationFrame(this.onAnimationFrame.bind(this));
  }

  render() {
    return <div ref={r => this.handleRef(r)} />;
  }
}

This component uses a ref on its root node, and depends on requestAnimationFrame for computing stuff around. when a condition is met, we call this.setState but it fails like this:

screen shot 2016-09-26 at 17 25 41
screen shot 2016-09-26 at 17 25 22

My understanding of the issue is that somehow track of my component's context was lost, but I don't have enough knowledge of react-lite's internals to put a finger on it.

Also, it works fine when I replace react-lite by react and react-dom.

Any idea of what could happen ?

@Lucifier129
Copy link
Owner

Lucifier129 commented Sep 27, 2016

Which version of react-lite did you use?

onAnimationFrame had better out of handleRef, just use handleRef to attach and detach ref

class MyComponent {
  componentDidMount() {
    if (condition) {
        this.onAnimationFrame()
    }
  }
  componentDidUpdate() {
    if (condition) {
        this.onAnimationFrame()
    }
  }
  componentWillUnmount() {
    this.cancelAnimationFrame()
  }
  handleRef(ref) {
    this.rootNode = ref;
  }
  cancelAnimationFrame() {
    cancelAnimationFrame(this.animationFrameID)
  }
  onAnimationFrame() {
    if (!this.rootNode) { return; }

    if (this.state.count < 10) {
        this.setState({ count: this.state.count + 1 });
    } // <-- this explodes.

    this.animationFrameID = requestAnimationFrame(this.onAnimationFrame.bind(this));
  }

  render() {
    return <div ref={r => this.handleRef(r)}>{this.state.count}</div>;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants