0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】オブジェクト型を初期化する際に `{ }` で初期化したらエラーになる

Posted at

概要

  • プリミティブ型: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 ?? ''} を渡すようにしてください。

引用:API Reference > コンポーネント > textarea

  • 先述のコードではオブジェクト型を 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:""}); // 修正
  };

参考資料

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?