How to handle early input to isomorphically rendered forms
I have a React app that includes a form, which is rendered server side, prepopulated with the user's work in progress. The problem is that if the user edits a value in the form before the app loads, then the app is unaware of the change. When the user saves, the unchanged data that was rendered by the server is re-saved, and the user's new data is dropped, although it is still shown in the form. In short, there seems to be a disconnect between React and input values in the markup that it replaces when initially loading.
I suppose I could put refs on every input and copy their values into the application state on componentDidMount, but there has got to be a better way. Has anyone else solved this problem?
Update
I am now of the opinion that the best way to solve this would be to have React take input values into account when creating checksums. GH issue: https://github.com/facebook/react/issues/4293
I suppose I could put refs on every input and copy their values into the application state on componentDidMount, but there has got to be a better way. Has anyone else solved this problem?
Browsers autofilling fields or remembering previous values across refreshes can also cause what is effectively the same issue - your app's view of the data being different from the user's.
My brute-force solution in the past has been to extract the complete form state from its inputs onSubmit
and re-run validaton before allowing submission to proceed.
Using componentDidMount
as you suggest sounds like a more elegant solution as it avoids the user entering invalid data and being allowed to try to submit it before they get any warnings. You don't need to add a ref
to every input, though; just add one to the <form>
and use its .elements
collection to pull all the data.
Suggested solution:
componentDidMount()
, pull the form's data from its .elements
(I extracted get-form-data from my form library for this purpose) Then from componentDidMount()
onwards, your app and the user will always be on the same page (literally).
If I understand you correctly, this is what is happening: https://jsfiddle.net/9bnpL8db/1/
var Form = React.createClass({
render: function () {
return <div>
<input type="text" defaultValue={this.props.defaultValue}/>
</div>;
}
});
// Initial form render without server-side data
React.render(<Form/>, $('#container')[0]);
setTimeout(function () {
// Simulate server-side render
$('#container').html(
// overwrites input
React.renderToString(<Form defaultValue="server1"/>)
);
}, 5000);
Server-side rendering should not be used to make updates. Rather, server-side rendering should be used to create the initial page, populating the inputs before the user ever has a chance to make changes. To solve your problem, I think you have a couple of options:
下一篇: 如何处理同构渲染表单的早期输入