概要
- プリミティブ型:
123
"文字列"
true
- オブジェクト型:
{}
[]
- プリミティブ型"以外"がこれに該当
- 今回は 『オブジェクト型の State 変数を初期化』 したら以下のエラーが確認された
Warning: A component is changing a controlled input to be uncontrolled.
This is likely caused by the value changing from a defined to undefined, which should not happen.
Decide between using a controlled or uncontrolled input element for the lifetime of the component.
エラーが生じたコード
Sample.jsx
import { useState } from "react";
const Example = () => {
// ユーザー情報
const personObj = { name: "Jack", age: 30 };
const [ person, setPerson ] = useState(personObj);
// nameの入力欄処理
const changeName = (e) => {
setPerson({ name: e.target.value, age: person.age });
};
// ageの入力欄処理
const changeAge = (e) => {
setPerson({ name: person.name, age: e.target.value });
};
// リセットボタン処理
const resetObj = () => {
setPerson({ }); // ココが原因
};
return(<>
<h3>Name:{person.name}</h3>
<h3>Age:{person.age}</h3>
<input type="text" onChange={ changeName } value={person.name} />
<input type="number" onChange={ changeAge } value={person.age} />
<div>
<button onClick={ resetObj }>リセット</button>
</div>
</>);
};
export default Example;
原因
あなたの value が API や state 変数から来ている場合、それが null や undefined に初期化されているかもしれません。その場合、まず空の文字列('')にセットするか、value が文字列であることを保証するために value={someValue ?? ''} を渡すようにしてください。
- 先述のコードではオブジェクト型を State 変数に格納していたため初期化のために
setPerson({});
で行っていたのがエラーの原因となっていた- このような初期化方法ではプロパティが undefined になってしまっている
Sample.jsx
const Example = () => {
const personObj = { name: "Jack", age: 30 };
const [ person, setPerson ] = useState(personObj);
/**(中略) **/
// リセットボタン処理
const resetObj = () => {
setPerson({}); // ココが原因
console.log(person); //=> {}
console.log(person.name); //=> undefined
console.log(person.age); //=> undefined
};
解決策
- オブジェクトを初期化するには先の公式ドキュメントの引用から 空文字(
""
)を入れる ことで解決可能
Sample.jsx
const Example = () => {
const personObj = { name: "Jack", age: 30 };
const [ person, setPerson ] = useState(personObj);
/**(中略) **/
// リセットボタン処理
const resetObj = () => {
setPerson({person.name: "", age:""}); // 修正
};
参考資料