title: Uncontrolled input of type text to be controlled warning
body: <p>I'm trying to create a multi step registration form using React and Redux.</p>
  
  <p>The main component is as follows :    </p>
  
  <pre><code>import React, {PropTypes} from 'react';
  import {connect} from 'react-redux';
  import {bindActionCreators} from 'redux';
  import * as actionCreators from '../../actions/actionCreators';
  import countries from '../../data/countries';
  
  import RegistrationFormStepOne from './registrationFormStepOne';
  import RegistrationFormStepTwo from './registrationFormStepTwo';
  import RegistrationFormStepThree from './registrationFormStepThree';
  import RegistrationFormStepFour from './registrationFormStepFour';
  
  class RegistrationPage extends React.Component {
      constructor(props) {
          super(props);
  
          this.state = {
              user: Object.assign({}, this.props.userData),
              fileNames: {},
              selectedFile: {},
              icons: {
                  idCard: 'upload',
                  statuten: 'upload',
                  blankLetterhead: 'upload',
                  companyPhoto: 'upload'
              },
              step: 1,
              errors: {}
          };
  
          this.setUser = this.setUser.bind(this);
          this.onButtonClick = this.onButtonClick.bind(this);
          this.onButtonPreviousClick = this.onButtonPreviousClick.bind(this);
          this.changeCheckboxState = this.changeCheckboxState.bind(this);
          this.onFileChange = this.onFileChange.bind(this);
          this.routerWillLeave = this.routerWillLeave.bind(this);
      }
  
      componentDidMount() {
          this.context.router.setRouteLeaveHook(this.props.route, this.routerWillLeave);
      }
  
      routerWillLeave(nextLocation) {
          if (this.state.step &gt; 1) {
              this.setState({step: this.state.step - 1});
              return false;
          }
      }
  
      getCountries(){
          return countries;
      }
  
  
      setUser(event) {
          const field = event.target.name;
          const value = event.target.value;
  
          let user = this.state.user;
          user[field] = value;
          this.setState({user: user});
  
      }
  
      validation(){
          const user = this.state.user;
          const languageReg = this.props.currentLanguage.default.registrationPage;
          let formIsValid = true;
          let errors = {};
  
          if(!user.companyName){
              formIsValid = false;
              errors.companyName = languageReg.companyNameEmpty;
          }
  
          if(!user.btwNumber){
              formIsValid = false;
              errors.btwNumber = languageReg.btwNumberEmpty;
          }
  
          if(!user.address){
              formIsValid = false;
              errors.address = languageReg.addressEmpty;
          }
  
          if(!user.country){
              formIsValid = false;
              errors.country = languageReg.countryEmpty;
          }
  
          if(!user.zipcode){
              formIsValid = false;
              errors.zipcode = languageReg.zipcodeEmpty;
          }
  
          if(!user.place){
              formIsValid = false;
              errors.place = languageReg.placeEmpty;
          }
  
  
          if(!user.firstName){
              formIsValid = false;
              errors.firstName = languageReg.firstnameEmpty;
          }
  
  
  
          this.setState({errors: errors});
          return formIsValid;
      }
  
      onFileChange(name, event) {
          event.preventDefault();
          let file = event.target.value;
  
          let filename = file.split('\\').pop(); //We get only the name of the file
          let filenameWithoutExtension = filename.replace(/\.[^/.]+$/, ""); //We get the name of the file without extension
  
          let user = this.state.user;
          let fileNames = this.state.fileNames;
          let selectedFile = this.state.selectedFile;
          let icons = this.state.icons;
  
          switch (name.btnName) {
              case "idCard" :
                  fileNames[name.btnName] = filenameWithoutExtension;
                  //Check if file is selected
                  if(file){
                      selectedFile[name.btnName] = "fileSelected";
                      user["idCardFile"] = true;
                      icons["idCard"] = "check";
                  }else{
                      selectedFile[name.btnName] = "";
                      user["idCardFile"] = false;
                      icons["idCard"] = "upload";
                  }
                  break;
              case "statuten" :
                  fileNames[name.btnName] = filenameWithoutExtension;
  
                  //Check if file is selected
                  if(file){
                      selectedFile[name.btnName] = "fileSelected";
                      user["statutenFile"] = true;
                      icons["statuten"] = "check";
                  }else{
                      selectedFile[name.btnName] = "";
                      user["statutenFile"] = false;
                      icons["statuten"] = "upload";
                  }
                  break;
              case "blankLetterhead" :
                  fileNames[name.btnName] = filenameWithoutExtension;
  
                  //Check if file is selected
                  if(file){
                      selectedFile[name.btnName] = "fileSelected";
                      user["blankLetterheadFile"] = true;
                      icons["blankLetterhead"] = "check";
                  }else{
                      selectedFile[name.btnName] = "";
                      user["blankLetterheadFile"] = false;
                      icons["blankLetterhead"] = "upload";
                  }
                  break;
              default:
                  fileNames[name.btnName] = filenameWithoutExtension;
                  //Check if file is selected
                  if(file){
                      selectedFile[name.btnName] = "fileSelected";
                      user["companyPhotoFile"] = true;
                      icons["companyPhoto"] = "check";
                  }else{
                      selectedFile[name.btnName] = "";
                      user["companyPhotoFile"] = false;
                      icons["companyPhoto"] = "upload";
                  }
          }
  
          this.setState({user: user, fileNames: fileNames, selectedFile: selectedFile, icons: icons});
      }
  
      changeCheckboxState(event) {
          let chcName = event.target.name;
          let user = this.state.user;
  
          switch (chcName) {
              case "chcEmailNotificationsYes":
                  user["emailNotifications"] = event.target.checked;
                  break;
              case "chcEmailNotificationsNo":
                  user["emailNotifications"] = !event.target.checked;
                  break;
              case "chcTerms":
                  if(typeof this.state.user.terms === "undefined"){
                      user["terms"] = false;
                  }else{
                      user["terms"] = !this.state.user.terms;
                  }
  
                  break;
              case "chcSmsYes":
                  user["smsNotifications"] = event.target.checked;
                  break;
              default:
                  user["smsNotifications"] = !event.target.checked;
          }
          this.setState({user: user});
          this.props.actions.userRegistration(this.state.user);
      }
  
      onButtonClick(name, event) {
          event.preventDefault();
          this.props.actions.userRegistration(this.state.user);
          switch (name) {
              case "stepFourConfirmation":
                  this.setState({step: 1});
                  break;
              case "stepTwoNext":
                  this.setState({step: 3});
                  break;
              case "stepThreeFinish":
                  this.setState({step: 4});
                  break;
              default:
                  if(this.validation()) {
                     this.setState({step: 2});
                  }
          }
      }
  
  
      onButtonPreviousClick(){
          this.setState({step: this.state.step - 1});
      }
  
      render() {
          const languageReg = this.props.currentLanguage.default.registrationPage;
  
          console.log(this.state.user);
          let formStep = '';
          let step = this.state.step;
          switch (step) {
              case 1:
                  formStep = (&lt;RegistrationFormStepOne user={this.props.userData}
                                                       onChange={this.setUser}
                                                       onButtonClick={this.onButtonClick}
                                                       countries={this.getCountries(countries)}
                                                       errors={this.state.errors}
                                                       step={step}/&gt;);
                  break;
              case 2:
                  formStep = (&lt;RegistrationFormStepTwo user={this.props.userData}
                                                       onChange={this.setUser}
                                                       onButtonClick={this.onButtonClick}
                                                       onButtonPreviousClick={this.onButtonPreviousClick}
                                                       errors={this.state.errors}/&gt;);
                  break;
              case 3:
                  formStep = (&lt;RegistrationFormStepThree user={this.props.userData}
                                                         onFileChange={this.onFileChange}
                                                         onButtonClick={this.onButtonClick}
                                                         onButtonPreviousClick={this.onButtonPreviousClick}
                                                         errors={this.state.errors}
                                                         fileNames={this.state.fileNames}
                                                         icons={this.state.icons}
                                                         fileChosen={this.state.selectedFile}/&gt;);
                  break;
  
              default:
                  formStep = (&lt;RegistrationFormStepFour user={this.props.userData}
                                                        onChange={this.setUser}
                                                        onChangeCheckboxState={this.changeCheckboxState}
                                                        onButtonClick={this.onButtonClick}
                                                        onButtonPreviousClick={this.onButtonPreviousClick}
                                                        errors={this.state.errors}/&gt;);
          }
  
          return (
              &lt;div className="sidebar-menu-container" id="sidebar-menu-container"&gt;
  
                  &lt;div className="sidebar-menu-push"&gt;
  
                      &lt;div className="sidebar-menu-overlay"&gt;&lt;/div&gt;
  
                      &lt;div className="sidebar-menu-inner"&gt;
                          &lt;div className="contact-form"&gt;
                              &lt;div className="container"&gt;
                                  &lt;div className="row"&gt;
                                      &lt;div className="col-md-10 col-md-offset-1 col-md-offset-right-1"&gt;
                                          {React.cloneElement(formStep, {currentLanguage: languageReg})}
                                      &lt;/div&gt;
                                  &lt;/div&gt;
                              &lt;/div&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          );
      }
  }
  
  RegistrationPage.contextTypes = {
      router: PropTypes.object
  };
  
  function mapStateToProps(state, ownProps) {
      return {
          userData: state.userRegistrationReducer
      };
  }
  
  function mapDispatchToProps(dispatch) {
      return {
          actions: bindActionCreators(actionCreators, dispatch)
      };
  }
  
  export default connect(mapStateToProps, mapDispatchToProps)(RegistrationPage);
  </code></pre>
  
  <p>The first step component is as follows</p>
  
  <pre><code>    import React from 'react';
  import Button from '../../common/formElements/button';
  import RegistrationFormHeader from './registrationFormHeader';
  import TextInput from '../../common/formElements/textInput';
  import SelectInput from '../../common/formElements/selectInput';
  
  const RegistrationFormStepOne = ({user, onChange, onButtonClick, errors, currentLanguage, countries}) =&gt; {
  
    const language = currentLanguage;
  
    return (
      &lt;div className="contact_form"&gt;
        &lt;form role="form" action="" method="post" id="contact_form"&gt;
          &lt;div className="row"&gt;
            &lt;RegistrationFormHeader activeTab={0} currentLanguage={language}/&gt;
            &lt;div className="hideOnBigScreens descBox"&gt;
              &lt;div className="headerTitle"&gt;{language.businessInfoConfig}&lt;/div&gt;
              &lt;div className="titleDesc"&gt;{language.businessBoxDesc}&lt;/div&gt;
            &lt;/div&gt;
            &lt;div className="col-lg-12"&gt;
              &lt;h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12"&gt;
                {language.businessDesc}
              &lt;/h6&gt;
              &lt;div className="clearfix"&gt;&lt;/div&gt;
              &lt;div className="col-sm-6"&gt;
                &lt;TextInput
                  type="text"
                  name="companyName"
                  label={language.companyNameLabel}
                  labelClass="control-label"
                  placeholder={language.companyNameLabel}
                  className="templateInput"
                  id="company"
                  onChange={onChange}
                  value={user.companyName}
                  errors={errors.companyName}
                /&gt;
              &lt;/div&gt;
              &lt;div className="col-sm-6"&gt;
                &lt;TextInput
                  type="text"
                  name="btwNumber"
                  label={language.vatNumberLabel}
                  placeholder={language.vatNumberLabel}
                  className="templateInput"
                  id="btwNumber"
                  onChange={onChange}
                  value={user.btwNumber}
                  errors={errors.btwNumber}
                /&gt;
              &lt;/div&gt;
  
              &lt;div className="col-sm-12" style={{marginBottom: 25}}&gt;
                &lt;TextInput
                  type="text"
                  name="address"
                  label={language.addressLabel}
                  placeholder={language.address1Placeholder}
                  className="templateInput"
                  id="address"
                  onChange={onChange}
                  value={user.address}
                  errors={errors.address}
                /&gt;
              &lt;/div&gt;
  
              &lt;div className="col-sm-12" style={{marginBottom: 25}}&gt;
                &lt;TextInput
                  type="text"
                  name="address1"
                  placeholder={language.address2Placeholder}
                  className="templateInput"
                  id="address"
                  onChange={onChange}
                  value={user.address1}
                  errors=""
                /&gt;
              &lt;/div&gt;
  
              &lt;div className="col-sm-12"&gt;
                &lt;TextInput
                  type="text"
                  name="address2"
                  placeholder={language.address3Placeholder}
                  className="templateInput"
                  id="address"
                  onChange={onChange}
                  value={user.address2}
                  errors=""
                /&gt;
              &lt;/div&gt;
  
                &lt;div className="col-sm-3"&gt;
                &lt;SelectInput name="country"
                             label={language.selectCountryLabel}
                             onChange={onChange}
                             options={countries}
                             className="templateInput selectField"
                             defaultOption={language.selectCountry}
                             value={user.country}
                             errors={errors.country}
                             /&gt;
                  &lt;/div&gt;
  
              &lt;div className="col-sm-3"&gt;
  
                &lt;TextInput
                  type="text"
                  name="zipcode"
                  label={language.zipcodeLabel}
                  placeholder={language.zipcodeLabel}
                  className="templateInput"
                  id="zipcode"
                  onChange={onChange}
                  value={user.zipcode}
                  errors={errors.zipcode}
                /&gt;
              &lt;/div&gt;
              &lt;div className="col-sm-6"&gt;
                &lt;TextInput
                  type="text"
                  name="place"
                  label={language.placeLabel}
                  placeholder={language.placeLabel}
                  className="templateInput"
                  id="place"
                  onChange={onChange}
                  value={user.place}
                  errors={errors.place}
                /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div className="clearfix"&gt;&lt;/div&gt;
            &lt;div className="col-lg-12" style={{marginLeft: 15, marginTop: 30}}&gt;
              &lt;Button onClick={onButtonClick.bind(this)}
                      name="stepOneNext"
                      value={language.btnNext}
                      icon="arrow-circle-right"
                      style={{margin: '0 auto 60px'}}/&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    );
  };
  
  export default RegistrationFormStepOne;
  </code></pre>
  
  <p>I try to add some simple validation and I've added validation function in my main component and then I check on button click if the returned value true or false is. If it's true, than I set step state to a appropriate value. And it works if I validate only the form fields of the first step, but when I try to also validate one or more form fields of the next step (now I'm trying to validate also the first field of the second step)</p>
  
  <pre><code>if(!user.firstName){
          formIsValid = false;
          errors.firstName = languageReg.firstnameEmpty;
      }
  </code></pre>
  
  <p>I get than </p>
  
  <p><em>Warning: TextInput is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.</em></p>
  
  <p>Without the validation function works everything perfect.</p>
  
  <p>Any advice?</p>
  
  <p><strong>EDIT</strong></p>
  
  <pre><code>    import React, {propTypes} from 'react';
  import _ from 'lodash';
  
  const TextInput = ({errors, style, name, labelClass, label, className, placeholder, id, value, onChange, type}) =&gt; {
    let wrapperClass = "form-group";
  
    if (errors) {
      wrapperClass += " " + "inputHasError";
    }
  
    return (
      &lt;div className={wrapperClass} style={style}&gt;
        &lt;label htmlFor={name} className={labelClass}&gt;{label}&lt;/label&gt;
        &lt;input type={type}
               className={className}
               placeholder={placeholder}
               name={name}
               id={id}
               value={value}
               style={{}}
               onChange={onChange}
        /&gt;
        &lt;div className="errorBox"&gt;{errors}&lt;/div&gt;
      &lt;/div&gt;
    );
  };
  
  TextInput.propTypes = {
    name: React.PropTypes.string.isRequired,
    label: React.PropTypes.string,
    onChange: React.PropTypes.func.isRequired,
    type: React.PropTypes.string.isRequired,
    id: React.PropTypes.string,
    style: React.PropTypes.object,
    placeholder: React.PropTypes.string,
    className: React.PropTypes.string,
    labelClass: React.PropTypes.string,
    value: React.PropTypes.string,
    errors: React.PropTypes.string
  };
  
  export default TextInput;
  </code></pre>
  
  <p>This is second step component : </p>
  
  <pre><code>import React from 'react';
  import Button from '../../common/formElements/button';
  import RegistrationFormHeader from './registrationFormHeader';
  import TextInput from '../../common/formElements/textInput';
  
  
  const RegistrationFormStepTwo = ({user, onChange, onButtonClick, onButtonPreviousClick, errors, currentLanguage}) =&gt; {
      const language = currentLanguage;
  
      return (
          &lt;div className="contact_form"&gt;
              &lt;form role="form" action="" method="post" id="contact_form"&gt;
                  &lt;div className="row"&gt;
                      &lt;RegistrationFormHeader activeTab={1} currentLanguage={language}/&gt;
                      &lt;div className="hideOnBigScreens descBox"&gt;
                          &lt;div className="headerTitle"&gt;{language.personalInfoConfig}&lt;/div&gt;
                          &lt;div className="titleDesc"&gt;{language.personalBoxDesc}&lt;/div&gt;
                      &lt;/div&gt;
                      &lt;div className="col-lg-12"&gt;
                          &lt;h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12"&gt;
                              {language.personalDesc}
                          &lt;/h6&gt;
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="firstName"
                                  label={language.firsnameLabel}
                                  placeholder={language.firsnameLabel}
                                  className="templateInput"
                                  id="name"
                                  onChange={onChange}
                                  value={user.firstName}
                                  errors={errors.firstName}
                              /&gt;
                          &lt;/div&gt;
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="lastName"
                                  label={language.lastnameLabel}
                                  placeholder={language.lastnameLabel}
                                  className="templateInput"
                                  id="name"
                                  onChange={onChange}
                                  value={user.lastName}
                                  errors={errors.lastName}
                              /&gt;
                          &lt;/div&gt;
  
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="phone"
                                  label={language.phoneLabel}
                                  placeholder={language.phoneLabel}
                                  className="templateInput"
                                  id="phone"
                                  onChange={onChange}
                                  value={user.phone}
                                  errors={errors.phone}
  
                              /&gt;
                          &lt;/div&gt;
  
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="mobilePhone"
                                  label={language.mobileLabel}
                                  placeholder={language.mobileLabel}
                                  className="templateInput"
                                  id="phone"
                                  style={{}}
                                  onChange={onChange}
                                  value={user.mobilePhone}
                                  errors={errors.mobilePhone}
                              /&gt;
                          &lt;/div&gt;
                          &lt;div className="clearfix"&gt;&lt;/div&gt;
  
                          &lt;div className="col-lg-12 col-md-12 col-sm-12 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="email"
                                  id="email"
                                  label={language.emailLabel}
                                  placeholder={language.emailLabel}
                                  className="templateInput"
                                  style={{}}
                                  onChange={onChange}
                                  value={user.email}
                                  errors={errors.email}
                              /&gt;
                          &lt;/div&gt;
  
                          &lt;div className="col-lg-12 col-md-12 col-sm-12 col-xs-12"&gt;
                              &lt;TextInput
                                  type="text"
                                  name="userName"
                                  label={language.usernameLabel}
                                  placeholder={language.usernameLabel}
                                  className="templateInput"
                                  id="name"
                                  onChange={onChange}
                                  value={user.userName}
                                  errors={errors.userName}
                              /&gt;
                          &lt;/div&gt;
  
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="password"
                                  name="password"
                                  label={language.passwordLabel}
                                  placeholder={language.passwordLabel}
                                  className="templateInput"
                                  id="password"
                                  onChange={onChange}
                                  value={user.password}
                                  errors={errors.password}
                              /&gt;
                          &lt;/div&gt;
                          &lt;div className="col-lg-6 col-md-6 col-sm-6 col-xs-12"&gt;
                              &lt;TextInput
                                  type="password"
                                  name="confirmPassword"
                                  label={language.passwordConfirmLabel}
                                  placeholder={language.passwordConfirmLabel}
                                  className="templateInput"
                                  id="password"
                                  onChange={onChange}
                                  value={user.confirmPassword}
                                  errors={errors.confirmPassword}
                              /&gt;
                          &lt;/div&gt;
  
                      &lt;/div&gt;
                      &lt;div className="clearfix"&gt;&lt;/div&gt;
                      &lt;div className="col-lg-6 col-xs-6" style={{marginTop: 30}}&gt;
                          &lt;Button onClick={onButtonPreviousClick}
                                  name="btnPrevious"
                                  value={language.btnPrevious}
                                  icon="arrow-circle-left"
                                  style={{marginRight: 10, float: 'right'}}/&gt;
                      &lt;/div&gt;
                      &lt;div className="col-lg-6 col-xs-6" style={{marginTop: 30}}&gt;
                          &lt;Button onClick={onButtonClick} name="stepTwoNext" value={language.btnNext}
                                  icon="arrow-circle-right" style={{marginLeft: 10, float: 'left'}}/&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/form&gt;
          &lt;/div&gt;
  
      );
  };
  
  export default RegistrationFormStepTwo;
  </code></pre>