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!