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

ReferenceError: document is not defined #1866

Closed
gasi opened this issue Jul 18, 2014 · 21 comments · Fixed by #1870
Closed

ReferenceError: document is not defined #1866

gasi opened this issue Jul 18, 2014 · 21 comments · Fixed by #1870

Comments

@gasi
Copy link
Contributor

gasi commented Jul 18, 2014

After upgrading from React 0.10 to 0.11 our componentWillMount handler fires during server-side rendering and ends up in getActiveElement which requires access to the DOM, i.e. document:

Redacted stack trace:

ReferenceError: document is not defined
    |     <<< async stack >>>
    |   at getActiveElement (~/workspace/project/node_modules/react/lib/getActiveElement.js:30:12)
    |   at ReactReconcileTransaction.ReactInputSelection.getSelectionInformation (~/workspace/project/node_modules/react/lib/ReactInputSelection.js:48:23)
    |   at ReactReconcileTransaction.Mixin.initializeAll (~/workspace/project/node_modules/react/lib/Transaction.js:175:30)
    |   at ReactReconcileTransaction.Mixin.perform (~/workspace/project/node_modules/react/lib/Transaction.js:140:12)
    |   at ReactUpdatesFlushTransaction.Mixin.perform (~/workspace/project/node_modules/react/lib/Transaction.js:141:20)
    |   at ReactUpdatesFlushTransaction.mixInto.perform (~/workspace/project/node_modules/react/lib/ReactUpdates.js:98:38)
    |   at Object.<anonymous> (~/workspace/project/node_modules/react/lib/ReactUpdates.js:176:19)
    |   at Object.flushBatchedUpdates (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at ReactDefaultBatchingStrategyTransaction.Mixin.closeAll (~/workspace/project/node_modules/react/lib/Transaction.js:214:42)
    |   at ReactDefaultBatchingStrategyTransaction.Mixin.perform (~/workspace/project/node_modules/react/lib/Transaction.js:155:16)
    |   at Object.ReactDefaultBatchingStrategy.batchedUpdates (~/workspace/project/node_modules/react/lib/ReactDefaultBatchingStrategy.js:70:19)
    |   at Object.enqueueUpdate (~/workspace/project/node_modules/react/lib/ReactUpdates.js:209:22)
    |   at [object Object].ReactCompositeComponentMixin.replaceState (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:871:18)
    |   at [object Object].ReactCompositeComponentMixin.setState (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:850:10)
    |   at [object Object].module.exports.React.createClass.setup (~/workspace/project/scripts/index.coffee:52:10)
    |   at [object Object].boundMethod [as setup] (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:1287:21)
    |   at [object Object].module.exports.React.createClass.componentWillMount (~/workspace/project/scripts/index.coffee:28:10)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:769:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactMultiChild.Mixin.mountChildren (~/workspace/project/node_modules/react/lib/ReactMultiChild.js:202:42)
    |   at [object Object].ReactDOMComponent.Mixin._createContentMarkup (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:198:32)
    |   at [object Object].ReactDOMComponent.Mixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactDOMComponent.js:120:14)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at [object Object].ReactCompositeComponentMixin.mountComponent (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:784:44)
    |   at [object Object].mountComponent (~/workspace/project/node_modules/react/lib/ReactPerf.js:57:21)
    |   at ~/workspace/project/node_modules/react/lib/ReactServerRendering.js:53:38
    |   at ReactServerRenderingTransaction.Mixin.perform (~/workspace/project/node_modules/react/lib/Transaction.js:141:20)
    |   at Object.renderComponentToString (~/workspace/project/node_modules/react/lib/ReactServerRendering.js:51:24)
@nickdima
Copy link

I have the same problem

@pierpanfilo
Copy link

I'm having the same problem.
I was so happy to see you finally added the hrefLang attribute support and tried to upgrade immediately.
Unfortunately this problem is keeping me from upgrading.

@gasi
Copy link
Contributor Author

gasi commented Jul 18, 2014

FYI, we worked around it by using componentDidMount which might work in your case too depending on your use case.

@petehunt
Copy link
Contributor

Wow this sounds like a big regression. Can you construct a simple repro case?

@gasi
Copy link
Contributor Author

gasi commented Jul 18, 2014

I will try but I probably won’t be able to until Sunday the earliest. Frankly, the error doesn’t happen with for every componentWillMount handler we have, so there might be something we’re doing wrong.

@sophiebits
Copy link
Collaborator

This might happen always if you setState within a componentWillMount? Agree that we need to fix this.

@nickdima
Copy link

For me it happens when I do setState in componentWillMount.
Will try to come up with the simplest repro case.

@petehunt
Copy link
Contributor

Oh, setState() is probably going through ReactUpdates which is using the (browser-specific as of 0.11) ReactReconcileTransaction I think.

@gasi
Copy link
Contributor Author

gasi commented Jul 18, 2014

Yes, we are using setState in the failing componentWillMount handler. Is that a bad practice?

@petehunt
Copy link
Contributor

@gasl maybe? why are you doing that vs getInitialState()?

@gasi
Copy link
Contributor Author

gasi commented Jul 18, 2014

Here’s the part of the stack trace (setup is the offending handler):

    |   at [object Object].ReactCompositeComponentMixin.setState (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:850:10)
    |   at [object Object].module.exports.React.createClass.setup (~/workspace/project/scripts/index.coffee:52:10)
    |   at [object Object].boundMethod [as setup] (~/workspace/project/node_modules/react/lib/ReactCompositeComponent.js:1287:21)

@nickdima
Copy link

This is the most simple example that reproduces the problem:

var React = require('react');

var HelloMessage = React.createClass({displayName: 'HelloMessage',
  componentWillMount:function () {
    this.setState({name: "Pete"});
  },
  render: function() {
    return React.DOM.div(null, "Hello ", this.props.name);
  }
});

console.log(React.renderComponentToString(HelloMessage({name: "John"})));

@petehunt
Copy link
Contributor

Trying to figure out if the right move is to fix setState() in componentWillMount() or instead forbid setState() in componentWillMount() in favor of getInitialState(). Thoughts @spicyj?

@sophiebits
Copy link
Collaborator

The former; we've always said this is supported.

@petehunt
Copy link
Contributor

but why do we support it? seems like "more than one way to do it"...

@sophiebits
Copy link
Collaborator

One use case is computing something based on props in both componentWillMount and componentWillReceiveProps; you can make a helper and call it in both places.

@petehunt
Copy link
Contributor

getInitialState() {
  return helper(this.props);
}

componentWillReceiveProps(nextProps) {
  this.setState(helper(nextProps));
}

does the same thing, no?

sophiebits added a commit to sophiebits/react that referenced this issue Jul 18, 2014
...when calling setState from within a componentWillMount. Fixes facebook#1866.

Test Plan: jest
@gasi
Copy link
Contributor Author

gasi commented Jul 18, 2014

@petehunt: The way our method is written, it’s more reusable to have setState in it vs. return values we’d then use for setState. Also, my understanding was that componentWillMount is only called in a DOM environment.

Based on your example, I can see now that calling setState is not very elegant in componentWillMount but disallowing it but would be a breaking change based on the current documentation: http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount

I’m ok with a breaking change in 0.x releases as long as it’s documented à la getDefaultProps change.

zpao added a commit that referenced this issue Jul 18, 2014
Don't initialize reconcile transaction on server
@zpao
Copy link
Member

zpao commented Jul 21, 2014

We're going to put out 0.11.1 with this (and a couple other ride-alongs). Thanks for bringing it to our attention!

@gasi
Copy link
Contributor Author

gasi commented Jul 21, 2014

👍 Thanks 😄

sophiebits added a commit that referenced this issue Jul 23, 2014
...when calling setState from within a componentWillMount. Fixes #1866.

Test Plan: jest

(cherry picked from commit 54d91c2)
@olance
Copy link

olance commented Jan 12, 2015

Hi guys!

The issue referenced above looks (reactjs/react-rails#146) related to this one... input welcome!

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

Successfully merging a pull request may close this issue.

7 participants