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

Add more specific error messages for bad callback in setState, replaceState, and ReactDOM.render #6310

Merged
merged 4 commits into from Mar 23, 2016

Conversation

Projects
None yet
3 participants
@gaearon
Copy link
Member

commented Mar 21, 2016

This builds on #5193 and introduces an important, in my opinion, detail (constructor function name) that makes issues like #6306 more easily identified.

Additionally, this removes the mention of methods that have been removed (setProps and replaceProps).

When using onClick={this.setState.bind(this, nextState)} by mistake, the error message says:

0.14

Uncaught Invariant Violation: enqueueCallback(...): You called setProps, replaceProps, setState, replaceState, or forceUpdate with a callback that isn't callable.

After #5193

Uncaught Invariant Violation: enqueueCallback(...): You called setProps, replaceProps, setState, replaceState, or forceUpdate with a callback of type object. A function is expected

After this PR

Uncaught Invariant Violation: setState(...): Expected the last optional callback argument to be a function. Instead received: SyntheticMouseEvent.


Why?

  • We don’t need to mention the APIs we removed (setProps, replaceProps).
  • enqueueCallback() is an implementation detail and is confusing to the user.
  • We have enough information to print the actual public API method name.
  • We need to make it clear what “callback” is. Many people don’t know these functions accept a callback. We need to tell them it’s the last optional argument.
  • Printing the constructor name (e.g. SyntheticMouseEvent) makes it much more clear why you get issues like #6306.
  • This error should also be enabled for ReactDOM.render() instead of just failing with a TypeError.
  • This adds tests.
@gaearon

This comment has been minimized.

Copy link
Member Author

commented Mar 21, 2016

I also noticed that top-level render does not have a similar protection and just fails with Uncaught TypeError: callback.call is not a function. I can look into fixing this as well, but at this point I would rather add tests so we don’t regress.

@facebook-github-bot

This comment has been minimized.

Copy link

commented Mar 21, 2016

@gaearon updated the pull request.

@facebook-github-bot

This comment has been minimized.

Copy link

commented Mar 21, 2016

@gaearon updated the pull request.

@facebook-github-bot

This comment has been minimized.

Copy link

commented Mar 21, 2016

@gaearon updated the pull request.

@gaearon

This comment has been minimized.

Copy link
Member Author

commented Mar 21, 2016

OK, this is ready for review. I changed error messages to include the specific method name and also added a descriptive error to ReactDOM.render failures.

cc @jimfb @zpao

@gaearon gaearon changed the title Make setState() callback error message more descriptive Add more specific error messages for bad callback in setState, replaceState, and ReactDOM.render Mar 21, 2016

@facebook-github-bot

This comment has been minimized.

Copy link

commented Mar 21, 2016

@gaearon updated the pull request.

@@ -138,14 +145,6 @@ var ReactUpdateQueue = {
},

enqueueCallbackInternal: function(internalInstance, callback) {
invariant(

This comment has been minimized.

Copy link
@gaearon

gaearon Mar 21, 2016

Author Member

I removed this one because it’s not enough for ReactDOM.render() code path. ReactMount calls the callback synchronously on the initial render so we would fail to print the error if we only checked here.

Currently ReactMount is the only thing using enqueueCallbackInternal. I could put an additional validateCallback call here too but then it would run twice on every initial render.

@jimfb

This comment has been minimized.

Copy link
Contributor

commented Mar 22, 2016

👍

@gaearon gaearon merged commit 1e81561 into facebook:master Mar 23, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@gaearon gaearon deleted the gaearon:setstate-warning branch Mar 23, 2016

@renovate renovate bot referenced this pull request Feb 2, 2018

Open

Update dependency react to v0.14.9 #29

0 of 1 task complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.