'React Material UI Label Overlaps with Text

I'm using Material UI in a React application and trying to implement an entity update page. In this, we would need to set the exiting values of the entity to let the user update them. The existing values have been set using the defaultValue attribute of the input fields:

<div className="input-field">
   <input type="text" name="name" ref="name" defaultValue={this.state.name} />
   <label htmlFor="name" >Name</label>
</div>

With this approach, the intended functionality works fine. However, the labels of all text fields overlaps with their values. Please see below screenshot:

enter image description here

If I click on each field, the label moves up as expected. However, at the page load, labels do not move up. I tried using the value attribute of the input fields together with the onChange() event handler but experienced the same problem. Really, appreciate your thoughts on this.

The complete source code of this application can be found here: https://github.com/imesh/react-examples/tree/master/meetups/meetups-web-client

This particular page can be found here: https://github.com/imesh/react-examples/blob/master/meetups/meetups-web-client/src/components/UpdateMeetup.js

Github Issue: https://github.com/Dogfalo/materialize/issues/5995



Solution 1:[1]

This is due to the undefined state of the value.

This workaround works for me as a fallback:

value= this.state.name || '';

e.g. for Material-UI

<div className="input-field">
   <input type="text" name="name" ref="name" value={this.state.name || ''} />
   <label htmlFor="name">Name</label>
</div>

Solution 2:[2]

InputLabel has a prop shrink. you can use in TextField like below:

<TextField
  // ... rest
  InputLabelProps={{ shrink: true }}  
/>

Solution 3:[3]

I solved this by using a condition if it is not null && undefined then assign the value otherwise "". Here use the Formik

<TextField
                    type="text"
                    label="Ending Month"
                    variant="outlined"
                    fullWidth
                    size="small"
                    name="endingMonth"
                    value={
                      values.endingMonth === null ||
                      values.endingMonth === undefined
                        ? ""
                        : values.endingMonth
                    }
                    helperText={touched.endingMonth && errors.endingMonth}
                    error={Boolean(touched.endingMonth && errors.endingMonth)}
                  />

Solution 4:[4]

I had the same issue; however it was inconsistent - meaning sometimes I have the labels displayed properly and sometimes overlapped

I tried the following and it worked fine. Basically the form is first rendered empty without data; then the useEffect was fetching the data and populating the data. I set a isLoading state variable - this will be initially set to true and set to false after the data is fetched by API.

Display all the data only after isLoading is false - this works well.

Code Snippet

export default function UserProfile(props) {
const classes = useStyles();
const [user, setUser] = React.useState({});
const [isLoading, setIsLoading] = React.useState(true);

const getUser = async () => {
    const requestOptions = {
        method: 'GET',
        cache: 'no-cache',
        headers: { 
            'Content-Type': 'application/json',
        },
        redirect: 'follow',
        referrerPolicy: 'no-referrer',            
    };

    const response = await axios.request(
        "/api/userprofile",
        requestOptions
    );

    const responseData = await response.data;
    
    setUser( responseData.userProfile );
    setIsLoading(false);
}

React.useEffect(() =>{
    getUser();
    console.log(user);
})

return(
    <div style={{padding:"10px"}}>
        <Grid container className={classes.card}>
            <Container component="main" maxWidth="xs">
            <>{ isLoading ? <div> </div> : 
            <div className={classes.paper}>
                <Typography variant="h6">User Profile</Typography>
                <TextField
                    key="Name"
                    variant="outlined"
                    margin="normal"
                    fullWidth
                    id="Name"
                    label="Name"
                    value={user.name}
                    InputProps={{
                        readOnly: true,
                    }}
                />
                <TextField
                    variant="outlined"
                    margin="normal"
                    fullWidth
                    id="email"
                    label="Email Address"
                    value={user.email}
                    InputProps={{
                        readOnly: true,
                    }}
                />
                <TextField
                    variant="outlined"
                    margin="normal"
                    fullWidth
                    id="phone"
                    label="Phone"
                    value={user.phone_number}
                    InputProps={{
                        readOnly: true,
                    }}
                />
            </div>
            }</>
            </Container>
        </Grid>
    </div>
);

}

Solution 5:[5]

I fixed it by adding the condition on shrink based on a text field value.

Just add this code in the text field: Updated (2022)

InputLabelProps={{ shrink: field.value?true:false }}  

Example:

<Controller
name="formatted_phone_number"
control={control}
render={({ field }) => (
  <TextField
    {...field}
    className=""
    id="formatted_phone_number"
    label="Phone"
    type="text"
    variant="outlined"
    fullWidth
    InputLabelProps={{ shrink: field.value?true:false }}  
  />
)}
/>

Solution 6:[6]

I can say whatever works for me try this out .

This is for Functional based Component.

 const Example = () =>{
   const [name, setName] = useState("");
    const editName = (name) =>{
    setName(name);
  }

        return(
          <TextField
            required
            variant="outlined"
            margin="normal"
            fullWidth
            value={name}
            onChange={e => setName(e.target.value)}
            label="Enter Name"
          />
      )
  }

Solution 7:[7]

Below worked:

<InputLabel shrink={true}>Select A Role</InputLabel>

InputLabelProps gave error in functional component in react.

Solution 8:[8]

Utilizing InputLabelProps={{shrink: true}}, you can add a state and an onSelect to toggle the shrink state

const [shrink1, setShrink1] = useState(false)

<TextField
            fullWidth
            id='filled-basic'
            label='Name'
            variant='filled'
            value={formState.name}
            onChange={(event) => setFormState({ name: event.target.value })}
            onSelect={() => setShrink1(true)}
            InputLabelProps={{ shrink: shrink1 }}
          />

Solution 9:[9]

It's 2022 and I still have this error; I have changed the wrapper element around TextField component from grid to div and it solved the issues for me.