Reputation:
I was trying to play off of the example code shown here in order to have an overlay trigger that displays a popover upon invalid username field regex for my form component. I'm getting the classic Cannot update during an existing state transition (such as within "render"). Render methods should be a pure function of props and state.
error upon trying to execute this code:
var UserField = React.createClass({
getInitialState: function() {
return {
value: ''
};
},
getValue: function() {
return this.refs.input.getValue();
},
validationState: function() {
let valueCode = this.state.value;
if (valueCode.length > 0) {
switch (valueCode.match(/^[A-Za-z0-9_-]+$/)) {
case null:
this.refs.userHint.show();
return 'warning';
break;
default:
this.refs.userHint.hide();
return '';
break;
}
}
},
handleChange: function() {
this.setState({
value: this.refs.input.getValue()
});
},
render: function() {
return (
<OverlayTrigger
ref="userHint"
trigger="manual"
placement="right"
overlay={<Popover title='Invalid Username Format'>
<strong>Warning!</strong> Valid user credentials only contain alphanumeric characters, as well as heifens and underscores.
</Popover>
}
>
<Input
type = 'text'
value = {this.state.value}
label = 'Username'
bsStyle = {this.validationState()}
ref = 'input'
groupClassName = 'input-group'
className = 'form-control'
onChange = {this.handleChange}
/>
</OverlayTrigger>
);
}
});
Any help on this is very much appreciated, as always. Thank you.
Upvotes: 2
Views: 3335
Reputation: 330
If I was developing this I would do it differently, with the Input
managing it's own validation and exposing whether it's valid or not through its state (accessible through refs
).
Without changing your approach, this should work better because it won't trigger changes in state of the parent component until the overlay has been shown or hidden:
validationState: function() {
let valueCode = this.state.value;
if (valueCode.length > 0) {
switch (valueCode.match(/^[A-Za-z0-9_-]+$/)) {
case null:
return 'warning';
break;
default:
return '';
break;
}
}
},
handleChange: function() {
let valueCode = this.refs.input.getValue();
if (valueCode.length > 0) {
switch (valueCode.match(/^[A-Za-z0-9_-]+$/)) {
case null:
this.refs.userHint.show();
break;
default:
this.refs.userHint.hide();
break;
}
}
this.setState({
value: valueCode
});
},
Upvotes: 2