I'm developing a website using React 15.1.0 and I'm experiencing unexpected behavior when creating input elements in my React component.
I have a React component which has a Step mechanism where the user fills out a form, goes to the next step, fills out another form etc.
I have these steps defined in an array containing objects formed like this:
this.steps = [{
stepHeading: 'Step 1',
stepDescription: 'Fill out the form part 1',
stepFormMarkup: (<div className="row row--highlighted ">
<div className="column form">
<fieldset className="forms js-forms forms--columns">
<FormInput
id="input_SSC"
type="text"
required={true}
label={this.labels.SSCInputLabel}
validation={email}
placeholder={this.labels.SSCInputLabel}
onChange={this.onEmailChanged}
/>
</fieldset>
</div>
</div>)
},
{
stepHeading: 'Step 2',
stepDescription: 'Fill out the form part 2',
stepFormMarkup: (<div className="row row--highlighted ">
<div className="column form">
<fieldset className="forms js-forms forms--columns">
<FormInput
id="input_email"
type="text"
required={true}
label={this.labels.EmailInputLabel}
validation={email}
placeholder={this.labels.EmailInputPlaceholder}
onChange={this.onEmailChanged}
/>
<FormInput
id="input_mobile"
type="text"
required={false}
label={this.labels.MobileInputLabel}
validation={phone}
placeholder={this.labels.MobileInputPlaceholder}
onChange={this.onMobileChanged}
/>
</fieldset>
</div>
</div>)
}];
I have a button click event that will increase the state property currentStep which then triggers a component update which should then render the markup from the next step in my this.steps array.
What happens is that whatever I type into input field from Step 1 will be auto inserted into the first input field of Step 2.
I haven't been able to find an explanation anywhere online.
Does anyone know if React somehow keeps "state" of the previous instance and mistakes it with the new instance?
Here is what my FormInput component looks like:
const FormInput = React.createClass({
this.id: 'input_id_missing',
propTypes: {
label: React.PropTypes.string,
placeholder: React.PropTypes.string,
type: React.PropTypes.string,
validation: React.PropTypes.func,
onChange: React.PropTypes.func,
required: React.PropTypes.bool
},
getInitialState() {
return {
validation: {}
};
},
handleInputChanged(event) {
this.validate(event.target.value);
},
validate(value) {
let validation = this.props.validation && this.props.validation(value);
this.setState({
validation: validation
});
if (typeof this.props.onChange === 'function') {
this.props.onChange(value, validation);
}
return validation;
},
render() {
return (
<div className={cx('form__field', {
'form__field--valid': (this.state.receivedInput && this.state.validation.valid),
'form__field--notvalid': (this.state.receivedInput && !this.state.validation.valid),
'form__field--labeled': this.props.label,
'form__field--not-labeled': !this.props.label
})}>
{this.props.label && (<label className="form__text form__label" htmlFor={this.props.id || this.id}>{this.props.label}</label>)}
{this.props.required && (<label className="form__text form__text--error form__label form__label--required" htmlFor={this.props.id || this.id}>( Required )</label>)}
<input id={this.props.id || this.id} type={this.props.type || 'text'} placeholder={this.props.placeholder} className="form__input form__text" onChange={this.handleInputChanged}/>
</div>
);
}
});