I'm rendering my React app at the document root, with server-side rendering.
I've got an email and password login form. It renders on the server without any state (both fields empty).
When the browser loads the page, the email and password are autofilled by the browser.
This happens before React bootstraps, and when it loads, it wipes out that state. So the user sees the inputs being autofilled then being emptied. Not ideal.
I tried using componentWillMount to grab the raw DOM node value and setState before render, but react complains that the checksum is invalid.
I realise this is a case where the DOM is being modified before react bootstraps on the client, but it would be good to be able to do this kinda stuff...
Update: A workaround I used was to pull the values out of the <input>s inside componentWillMount, then setState to those values inside componentDidMount. Would still be nice to handle this cleanly though...
I have a feeling the "proper" way to fix this would be to have a prop like autofillValue on ReactDOMInput. Then on the first render of a client, if true, the component can grab that new value and run the onChange handler to incorporate it.
React does know when it's reusing markup that came from the server. So this should be possible.
However willMount+didMount does feel a bit hacky and the bits of information React exposes on when it's doing its first render from server generated markup is quite a low-level implementation detail.
For that reason it may be worthwhile to introduce a new lifecycle event like componentWillReuseNode that accepts the old DOM node as an argument.
Then anything like values injected by a browser can be optionally slurped up by nodes like ReactDOMInput and incorporated into the React flow.
@keyanzhang @zpao
Got the same problem here. It looks like a timing problem to me:
By delaying the rendering of react on browser-side by 200ms, the password field will be cleared. Not so without the delay.
I traced the problem down to ReactDOMInput#L236.
The node.value of the password field is an empty string, even if the browser auto-filled it.
And the node.value = node.value clears it.
I created a repository to reproduce it, since writing a test is hard. _Tested on Chrome 56._
_Edit: Can someone confirm that this is a misbehaviour by react?_
@mosch were you ever able to find a solution?
EDIT: I created a test case that can be found here: https://github.com/chrisblossom/react/commit/23bc06d893d854ec5ef8f71d9dcbbd9de2c5df39.
@chrisblossom not really (except hotfixing this line, by not doing it).
I created an input wrapper to solve this race condition. If anyone has any suggestions on how to fix any of the known issues please open a ticket/PR. https://github.com/chrisblossom/react-safe-universal-inputs
Merging this with https://github.com/facebook/react/issues/4293
@aweary Did you mean to link a different issue? This is #2585
@chrisblossom fixed, thanks
Most helpful comment
@keyanzhang @zpao
Got the same problem here. It looks like a timing problem to me:
By delaying the rendering of react on browser-side by 200ms, the password field will be cleared. Not so without the delay.
I traced the problem down to ReactDOMInput#L236.
The node.value of the password field is an empty string, even if the browser auto-filled it.
And the
node.value = node.valueclears it.I created a repository to reproduce it, since writing a test is hard. _Tested on Chrome 56._
_Edit: Can someone confirm that this is a misbehaviour by react?_