MUI Autocompleteでuncontrolledの注意が出た時の対応方法の話

今回はMUI(Material UI)のAutocompleteで注意が出て解消が大変だったのでメモとして残しておきます

はじめにシンプルな構成でエラーが発生するソースを書いておきます

動作はAutocompleteのシンプルな使い方です
映画タイトルをtop100Filmsに入れて、表示させます。
選択を変更時にfilm変数に値を入れる

って動作です


import React from "react";
import { Autocomplete, TextField } from "@mui/material";

interface Film {
    title: string;
    year: number;
}

const MUIAutocompleteWarning = () => {
    const [film, setFilm] = React.useState<Film | null>();

    const top100Films: Film[] = [
        { title: 'The Shawshank Redemption', year: 1994 },
        { title: 'The Godfather', year: 1972 },
        { title: 'The Godfather: Part II', year: 1974 },
        { title: 'The Dark Knight', year: 2008 },
    ];

    return (
        <>
            <Autocomplete
                options={top100Films}
                value={film}
                getOptionLabel={(option) => option.title}
                style={{ width: 300 }}
                renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
                onChange={(e, data) => setFilm(data)}
            />
        </>
    );
}

export default MUIAutocompleteWarning

しかし、選択を切り替えると以下のエラーがコンソールに吐き出します。


MUI: A component is changing the uncontrolled value state of Autocomplete to be controlled.
Elements should not switch from uncontrolled to controlled (or vice versa).
Decide between using a controlled or uncontrolled Autocomplete element for the lifetime of the component.
The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.
More info: https://fb.me/react-controlled-components

今回はこのエラーの解消方法を書いておきます

エラー文言を考える

はじめに文言を確認しますが… よくわかりません!

対策後に単語だけを読んでみると以下の様です

Autocompleteのstateがuncontrolledとなるのが問題
valueがundefinedじゃねぇ?

解消方法

ポイントはvalueにあります

注意にある通りにundifinedになっています。

明示的にnullを入れることで解消できます


  value={film ?? null}

or


  value={film || null}

終いに

今回はエラーメッセージを読み解けば修正は楽でしたが、ソース自体はシンプルすぎて原因の判明に時間がかかりました

useState()の未指定状態だったらundefinedとなる
Autocompleteはvalueにundefined入れるとuncontrolledとエラーが出る

って部分がポイントでしょうね

今回はシンプル状態にサンプルソースを作りましたが、実装はもう少し複雑なので…
これ以上になるとMUIの中身が原因かもと思っていました

ま、エラーメッセージはちゃんと読みましょう!と言うことでですね

サンプルデータは生成AIが作ってくれたのでそれを使っています