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

Improve not-yet-mounted setState warning #12531

Merged
merged 2 commits into from
Apr 3, 2018
Merged

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Apr 3, 2018

This is similar to #12347, but for when you call setState or forceUpdate too early. I tweaked the wording to have more actionable suggestions.

'To fix, assign the initial state in the MyComponent constructor. ' +
'If the state needs to reflect an external data source, ' +
'you may also add a componentDidMount lifecycle hook to MyComponent ' +
'and call setState there if the external data has changed.',
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this one is for forceUpdate I figured we should push people to use this.state = ... and setState here anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, no strong feelings about this I guess.

@@ -225,6 +225,86 @@ describe('ReactCompositeComponent', () => {
expect(inputProps.prop).not.toBeDefined();
});

it('should warn about `forceUpdate` on not-yet-mounted components', () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note these are not new warnings. Just new tests for an existing warning.

callerName,
"Can't call %s on a component that is not yet mounted. " +
'This is a no-op, but it might indicate a bug in your application. ' +
'To fix, assign the initial state in the %s constructor. ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Might read nicer with "\n\n" between these two sections?

'This usually means you called %s() on an unmounted component. ' +
'This is a no-op.\n\nPlease check the code for the %s component.',
callerName,
"Can't call %s on a component that is not yet mounted. " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I like this message better- but this first sentence seems less accurate and maybe confusing, since you can call setState from componentWillMount/UNSAFE_componentWillMount.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't want to encourage those methods (and will start warning for them in the future) I wouldn't worry about them.

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh shrug Ok

'To fix, assign the initial state in the MyComponent constructor. ' +
'If the state needs to reflect an external data source, ' +
'you may also add a componentDidMount lifecycle hook to MyComponent ' +
'and call setState there if the external data has changed.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, no strong feelings about this I guess.

Copy link
Collaborator

@sophiebits sophiebits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just for constructor? I think it is.

@gaearon gaearon merged commit 36c2939 into facebook:master Apr 3, 2018
@gaearon
Copy link
Collaborator Author

gaearon commented Apr 3, 2018

@sophiebits Yes, it's just for constructor. The renderer will later override the updater property. Is that bad?

'This is a no-op.\n\nPlease check the code for the %s component.',
callerName,
"Can't call %s on a component that is not yet mounted. " +
'This is a no-op, but it might indicate a bug in your application.\n\n' +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't call %s on a component before mounting it. This is a no-op, but it likely indicates a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state.

^ Maybe? It looks a little wordy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want to drop the second part? I thought it's kind of important because these issues will get more prominent with async.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I see what you mean. If this only affects constructor we might as well not talk about this.

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

Successfully merging this pull request may close these issues.

4 participants