LoginSignup
6
3

More than 1 year has passed since last update.

【MaterialUI】TextFieldでラベルと文字が重なってしまう状態の対処法【React】

Last updated at Posted at 2021-05-06

症状

MaterialUIのTextFieldに初期値を設定して、実装。実装した画面でブラウザをリロードすると、以下のようにラベルと初期値が重なってしまう事象が発生しました。
フォーカスすると、ラベルが上に動き正常な状態になりますが、フォーカスを外すとこの状態に戻ってしまいます。

image.png

以下が今回使ったMaterialUIの部品のコードになります。

MaterialUITextField
import React, { Fragment,useState,useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

const useStyles = makeStyles((theme) => ({
  root: {
    '& .MuiTextField-root': {
      margin: theme.spacing(1),
      width: '25ch',
    },
  },
}));

export function react:MaterialUITextField(prop) {
    const classes = useStyles();
    const [value, setValue] = useState(prop.name);

    const handleChange = (event) => {
      setValue(event.target.value);
    };

    return (
    <wrapper>
      <Fragment>
        <form className={classes.root} noValidate autoComplete="off">
        <div>
        <TextField
          id="outlined-multiline-static"
          label="名前"
          multiline
          rows={4}
          defaultValue={value}
          variant="outlined"
          onChange={handleChange}
        />
      </div>
      </form>
    </Fragment>
    }
    </wrapper>
  );
}

同様のエラーが他の方でも発生しているようで、valueの中身がnull,undefindの時に事象が発生するとのこと。
console.logでvalue値を確認したところ、初回レンダリングのときにはundefindになっていることを確認。

また、ログと事象を観察すると、2回目以降で正しく値が取得でき初期値の更新ができても、初期値が入るのみでラベルが被る事象は解消されないようでした。
そのことから、初回レンダリング時のうまく処理をしなければいけないということが分かりました。

そう考えて以下のコードを追加しましたが、上手く機能しませんでした。

materialUITextField
useEffect(()=>{
  setValue("")
},[])

また、ほかの方が解決した方法も試しましたが、解決できませんでした。

defaultValue={value===undefined? "":value}

解決方法

useStateを使い、初期値であるvalueに値が設定されるまでtextfieldを読み込ませないようにすることで、エラーを回避できました。
以下が解決時のコードになります。

valueの値がundefindやnullなどの未設定状態のときはLOADINGの文字が表示されるようにし、valueの値にporpの値が設定されたときにTextFiledを表示させるように制御しました。

MaterialUITextField
import React, { Fragment,useState,useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

const useStyles = makeStyles((theme) => ({
  root: {
    '& .MuiTextField-root': {
      margin: theme.spacing(1),
      width: '25ch',
    },
  },
}));

export function MaterialUITextField(prop) {
    const classes = useStyles();
    const Fooddescription = food.description
    const [value, setValue] = useState(prop.name);

    const handleChange = (event) => {
      setValue(event.target.value);
    };

    //propの値が変更された時に処理される
    useEffect(() => {
      setValue(prop.name);
    }, [prop]);

    return (
    <wrapper>
      {
      value === undefined || value === null? //ここでvalue値の判定をしている
      //valueが未設定の場合の処理
      <Fragment>
          LOADING
      </Fragment>
      :
   //valueが設定済みになった時の処理
      <Fragment>
        <form className={classes.root} noValidate autoComplete="off">
        <div>
        <TextField
          id="outlined-multiline-static"
          label="名前"
          multiline
          rows={4}
          defaultValue={value===undefined? "":value} //念のためここでも制御するが、たぶんいらない
          variant="outlined"
          onChange={handleChange}
        />
      </div>
      </form>
    </Fragment>
    }
    </wrapper>
  );
}

参考

MaterialUI Text Field (テキストフィールド)
https://material-ui.com/ja/components/text-fields/

javascript : React MaterialUIラベルがテキストと重なっています
https://www.fixes.pub/program/282923.html

react,material-uiのselectにて、labelと要素が重なって表示される
https://ja.stackoverflow.com/questions/54793/react-material-ui%E3%81%AEselect%E3%81%AB%E3%81%A6-label%E3%81%A8%E8%A6%81%E7%B4%A0%E3%81%8C%E9%87%8D%E3%81%AA%E3%81%A3%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3