Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form initialValues are not prepopulated on the UI after initialize when Redux DevTools is disabled #3879

Open
ekscentrysytet opened this issue Mar 1, 2018 · 0 comments

Comments

@ekscentrysytet
Copy link

ekscentrysytet commented Mar 1, 2018

Are you submitting a bug report or a feature request?

Bug report

What is the current behavior?

Here's my form component:

const mapStateToProps = state => ({
  ...state.profile.twoFactorAuth,
  formValues: getFormValues('twoFactorAuthentication')(state),
  currentUser: state.currentUser.user,
})

const mapDispatchToProps = {
  changeFormValue: change,
  toggleShouldVerifyPhoneNumber,
}

class TwoFactorAuthenticationForm extends React.Component {
  componentWillReceiveProps(nextProps) {
    const {
      isEnabledTwoFactorAuth,
      changeFormValue,
      formValues,
      toggleShouldVerifyPhoneNumber,
      shouldVerifyNumber,
    } = this.props

    // cleat two factor type and toggle off 2FA
    if (!nextProps.isEnabledTwoFactorAuth && isEnabledTwoFactorAuth) {
      changeFormValue('twoFactorAuthentication', 'type', null)
    }

    // reset phone number verification
    if (
      shouldVerifyNumber &&
      formValues.type === 'phone' &&
      nextProps.formValues.type !== formValues.type
    ) {
      toggleShouldVerifyPhoneNumber()
    }
  }

  componentWillUnmount() {
    const {
      formValues,
      currentUser,
      changeFormValue,
    } = this.props

    if (!currentUser.two_factor_type && formValues.type) {
      changeFormValue('twoFactorAuthentication', 'type', null)
    }
  }

  getSubmitBtnLabel() {
    const {
      shouldVerifyNumber,
    } = this.props;

    return shouldVerifyNumber ? 'Verify' : 'Save'
  }

  renderTwoFactorFields() {
    const {
      formValues,
      shouldVerifyNumber,
    } = this.props

    if (!formValues || formValues.type === 'email') return null

    if (formValues.type === 'phone') {
      return (
        <div>
          <div>
            <Field
              name="phone"
              label="Phone"
              // mask="+1 (999) 999-9999"
              mask="+99 (999) 999-9999"
              component={FormInput}
              fixedLabel
              validate={required} />
          </div>
          <p>
            PLEASE NOTE: We will send verification codes by SMS text messages to the number you provide above.
            You should verify phone number before activation. If you do not verify your number it will be blocked.
            To unblock number please contact support.
          </p>
          {
            shouldVerifyNumber &&
              <Field
                name="code"
                label="Verification code"
                component={FormInput}
                fixedLabel
                validate={required} />
          }
        </div>
      )
    }
  }

  renderTwoFactorTypeSelect() {
    return (
      <Field
        name="type"
        component={FormRadioGroup}>
        <RadioButton
          value="phone"
          label="Send security codes to me via Text/SMS" />
        <RadioButton
          value="email"
          label="Send security codes to me via Email at the address above" />
      </Field>
    )
  }
  
  render() {
    const {
      error,
      handleSubmit,
      valid,
      dirty,
      isEnabledTwoFactorAuth,
    } = this.props    

    return (
      <form onSubmit={handleSubmit}>
        {
          isEnabledTwoFactorAuth && this.renderTwoFactorTypeSelect()
        }
        {
          isEnabledTwoFactorAuth && this.renderTwoFactorFields()
        }
        {
          error &&
          <div className="form-error">{ error }</div>
        }
        <RaisedButton
          type="submit"
          primary
          disabled={!valid || !dirty}
          label={this.getSubmitBtnLabel()} />
      </form>
    )
  }
}

TwoFactorAuthenticationForm = reduxForm({
  form: 'twoFactorAuthentication',
  destroyOnUnmount: false,
  enableReinitialize: true,
})(TwoFactorAuthenticationForm);

module.exports = connect(mapStateToProps, mapDispatchToProps)(TwoFactorAuthenticationForm)

initialValues are stored in reducer:

const initialState = {
  loading: false,
  isEnabledTwoFactorAuth: false,
  shouldVerifyNumber: false,
  updateMessage: null,
  initialValues: null,
  error: null,
}

const twoFactorAuth = (state = initialState, action) => {
  switch (action.type) {
    case CURRENT_USER_FETCH.SUCCESS:
      return {
        ...state,
        isEnabledTwoFactorAuth: !!action.payload.user.two_factor_type,
        initialValues: {
          type: action.payload.user.two_factor_type,
          phone: action.payload.user.phone,
        },
      }
...

CURRENT_USER_FETCH.SUCCESS action type is dispatched before any component is mounted to DOM (except root App component)

The problem is when Redux Devtools is disabled in browser the form field value doesn't get prepopulated (tested in Chrome and Firefox)
form_issue

But when I enable DevTools I'm able to get value prepopulated:
image

What is the expected behavior?

Field values are prepopulated

What's your environment?

Redux form version: 7.2.3

@ekscentrysytet ekscentrysytet changed the title Form initialValues are not displayed on the UI after initialize when Redux DevTools is disabled Form initialValues are not prepopulated on the UI after initialize when Redux DevTools is disabled Mar 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant