Rmwc: Controlled TextField with required enabled initially renders invalid

Created on 6 Sep 2018  路  14Comments  路  Source: jamesmfriedman/rmwc

Package Versions

react: ^16.4.2
rmwc: ^1.9.4
material-components-web: ^0.39.1

From https://github.com/jamesmfriedman/rmwc/issues/280

If you have a controlled TextField with required set it will initially render as invalid due to the initial syncing of the React component props to the MDC component internal state. However, required fields should not render as invalid until they lose focus or the form is submitted.

Example:

import * as React from 'react'

// Components
import { TextField, TextFieldIcon } from 'rmwc/TextField'

// Types
export interface Props {
  value: string
  onChange: (username: string) => void
}

export default class UsernameInput extends React.PureComponent<Props> {
  public render() {
    return (
      <TextField
        outlined
        required
        label={"Username"}
        value={this.props.value}
        onChange={this.onChange}
        withLeadingIcon={<TextFieldIcon icon='person' />}
      />
    )
  }

  // Event handlers
  private onChange = (evt: React.FormEvent<HTMLInputElement>) =>
    this.props.onChange(evt.currentTarget.value)
}
MDC bug

Most helpful comment

@rjdestigter every once in a while I comb through the mat-web-react issues and I found the same one. Looks like this is upstream. I'll still look to see if I can patch the adapter / foundation which I've done in a few other cases to hack around the problem.

All 14 comments

This was fixed with the release of 1.9 since MDC overhauled their internal validation checks. Please reopen if you are still seeing issues.

  • @jamesmfriedman

Re-opened as I am still encountering this issue.

As a workaround (for now), you can either set the text field to valid after mounting or remove the required from the textfield and set it after mounting.

I created a code sandbox:
https://codesandbox.io/s/j239839xy

Thanks for the repro @j-o-d-o and the workaround. I'll be able to fix it appropriately now.,

@rjdestigter every once in a while I comb through the mat-web-react issues and I found the same one. Looks like this is upstream. I'll still look to see if I can patch the adapter / foundation which I've done in a few other cases to hack around the problem.

Verified this will be fixed with the release of MDC 40 and RMWC 3.0.0

Thanks for reporting. Experiencing a few regressions with 3.0.7. I鈥檇 recommend downgrading to the previous version for the time being.

I just had a crack at fixing it.

I've gone back a few releases but it's still not working. I think my fix isn't going to hack it without access to the previous props in the sync method so you can choose to only call setValue if the value has actually changed (so the first sync won't call it, and the invalid classes won't be applied.)

This fixes the issue:

class Text extends TextField {
  sync() {}

  componentDidUpdate(prevProps) {
    if (prevProps.value !== this.props.value) {
      super.sync(this.props);
    }
  }
}

Thank you!

Should be out with todays patch. Added a test case to make sure this doesn't regress again, although due to having to patch native input validity onto JSDOM, I can't seem to get the full test case to work which would be render valid -> focus -> blur -> invalid.

JSDOM still doesn't do validity? Ugh.

It kind of does with a polyfill I added in, but it鈥檚 more of an issue of JSDOM not mimicking the exact same validity behavior when you focus and then blur a required field (which should set it as invalid)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sangdth picture sangdth  路  5Comments

nicholaschiang picture nicholaschiang  路  4Comments

UFOMelkor picture UFOMelkor  路  6Comments

filbertteo picture filbertteo  路  3Comments

hronro picture hronro  路  3Comments