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

Race condition on <Can /> #128

Closed
dfee opened this issue Nov 8, 2018 · 5 comments
Closed

Race condition on <Can /> #128

dfee opened this issue Nov 8, 2018 · 5 comments

Comments

@dfee
Copy link
Contributor

dfee commented Nov 8, 2018

Well, it might not actually be a race condition, as the intended action loses every time, but:

When the component's componentWillReceiveProps is called with a new Ability instance, a setState is called, and then the component's connectToAbility is called which ultimately fires off this.recheck().

componentWillReceiveProps(props) {
if (props.ability && this.state.ability !== props.ability) {
this.setState({ ability: props.ability });
this.connectToAbility(props.ability);
} else {
this.recheck(props);
}
}

That method (this.recheck) calls this.check and uses this.props as params and this.state.ability as the ability. However, the call stack is still nested under componentWillReceiveProps, so the props we're rechecking against are the old props, and the state is most likely not the (now updated) state (see: https://reactjs.org/docs/react-component.html#setstate)!

The result is that the render method uses this.state.allowed which was (likely) produced erroneously as described above.

Therefore a good solution to this problem is to move the call to connectToAbility into the setState callback:

  componentWillReceiveProps(props) {
    if (props.ability && this.state.ability !== props.ability) {
      this.setState({ ability: props.ability }, () => {
        this.connectToAbility(props.ability);  // or this.state.ability
      });
    } else {
      this.recheck(props);
    }
  }
@dfee
Copy link
Contributor Author

dfee commented Nov 8, 2018

I tried to fork, clone, and test the package before making any changes (and a pull request), but I can't figure out how to get the tests to run.

@dfee
Copy link
Contributor Author

dfee commented Nov 8, 2018

Alright, figured out how to get it to run, and submitted a PR #129

@stalniy
Copy link
Owner

stalniy commented Nov 8, 2018

I see. Thanks for the issue!

@stalniy stalniy closed this as completed in 9d0c839 Nov 8, 2018
@stalniy
Copy link
Owner

stalniy commented Nov 8, 2018

published in @casl/[email protected]

@dfee
Copy link
Contributor Author

dfee commented Nov 8, 2018

Thanks for the quick update!

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