この記事を作った動機

 React + Zustand + TypeScirpt の組み合わせで、Input タグにて躓いたことがあったので記録したい。具体的な症状としては、要素の内容を変更しようとしても、一切微動だにせず、値を変えることができないという症状がある。

問題の挙動

期待する挙動

問題が起こったコード

問題がない部分

// ...
            <LabelTextEntryItem
                name="IP / URL"
                callback={(resultString:string) => {
                    setNetwork((prev) => ({
                        ...prev,
                        IPorDomainName: resultString
                    }))
                }}
                init={getNetwork().IPorDomainName}
            ></LabelTextEntryItem>
// ...

問題がある部分

// ...
export function LabelTextEntryItem({ name , init , callback}:{ name:string, init:string , callback:(result:string) => void }){
    return <div className="flex flex row mb-4">
        <div className="label text-xl noSelect">{name}:</div>
        <div className="ml-auto">
            <HoverAnimation>
                // 問題の箇所 --------------------
                // 問題の箇所 --------------------
                <input className="ml-auto text-xl w-30" id="entry" value={init} type="text" onChange={(event:ChangeEvent<HTMLInputElement>) => {
                    callback(event.target.value)
                }}></input>
                // 問題の箇所 --------------------
                // 問題の箇所 --------------------
            </HoverAnimation>
        </div>
    </div>
}
// ...

解決に至った方法

 問題が再現する条件として、Zustandで定義したストアの内容をInputタグにて表示するときにvalueの引数としてそれを指定していることがある。解決のためには、defaultValueとしてZustand内の内容を表示するようにすることで解決された。なぜこれで症状が解決するのかは分かってない。コンソールでコールバックが呼ばれたときの内容を確認してみたところ、valueとして引数にZustandの内容を与えても、値自体は更新された値がコールバックに正しく伝達できていることが確認でき、コールバック内の値の更新処理が上手くいかない理由が不明である。defaultValueとvalueのinputタグにおける違いとは多分値の拘束力なのではないか?と思われる。valueに固定値を指定してしまうと、編集不能になるとかでもあるのだろうか?

修正結果

// ...
export function LabelTextEntryItem({ name , init , callback}:{ name:string, init:string , callback:(result:string) => void }){
    return <div className="flex flex row mb-4">
        <div className="label text-xl noSelect">{name}:</div>
        <div className="ml-auto">
            <HoverAnimation>
                // 問題の箇所 --------------------
                // 問題の箇所 --------------------
                <input className="ml-auto text-xl w-30" id="entry" defaultValue={init} type="text" onChange={(event:ChangeEvent<HTMLInputElement>) => {
                    callback(event.target.value)
                }}></input>
                // 問題の箇所 --------------------
                // 問題の箇所 --------------------
            </HoverAnimation>
        </div>
    </div>
}
// ...

試したこと

 「defaultValueとvalueのinputタグにおける違いとは多分値の拘束力なのではないか?と思われる。valueに固定値を指定してしまうと、編集不能になるとかでもあるのだろうか?」という疑問があり、以下のような要素を対応する実験として試したところ、問題の挙動にて示した症状が再現することが分かった。

            <input type="text" value={"afdsdf"}></input>

参考にしたサイトとか

 今回は特になし。