-
Notifications
You must be signed in to change notification settings - Fork 49.8k
Description
Consider, for example, a relatively generic <Field /> component:
var fieldCounter = 0;
var Field = React.createClass({
getInitialState: function() {
return { inputId: 'field-' + ++fieldCounter };
},
render: function() {
var props = this.props,
inputId = this.state.inputId;
return (
<div className='field'>
<label htmlFor={inputId}>{props.label}</label>
<input type={props.type} id={inputId} name={props.name} value='' />
</div>
);
}
});In order for the <label /> tag to be semantically related to the <input /> tag, we obviously need to match the for attribute to the <input /> tag's id attribute. Outside of that requirement, however, we have no need of the id attribute, so a solution like the one above is convenient as it handles that all internally, with no need for a consuming component to pass in an actual id value.
The problem I'm running into, however, is that this causes the id attributes generated client-side to mismatch what was sent down by the server (the client-side fieldCounter restarts at 0 on every load, whereas the server-side reference obviously just keeps growing).
This mismatch then results in an error being thrown:
Invariant Violation: You're trying to render a component to the document using server rendering [...]
So, my question is this: am I overlooking an obvious solution here? I would like for the <Field /> component to be able to simply internalize the id generation as an implementation detail, but I can't seem to come up with a good mechanism for then matching up that id generation client-side.
Thanks in advance!