【React Hooks】useState()でcannot assign to read only propertyが出た時の対処法


はじめに

useState()でオブジェクトを管理していましたが、タイトルのようなエラーが発生したので、その解決法を記してあります。

エラー時のコード

test.js
import React, { useState, useEffect } from "react";
import { db } from "../firebase.js";

const Test = () => {
  const [imgStyle, setImgStyle] = useState({backgroundImage: ""});

  useEffect(() => {

   db.collection("test").get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        const docVal = doc.data();
        imgStyle["backgroundImage"] = `url(${docVal.imgUrl})`;
        setImgStyle(Object.assign({}, imgStyle));
      });
    }).catch(function(error) {
      console.log("Error getting document:", error);
    });

  }, []);

  return (
    <div>
      <div className="reportBefore" style={imgStyle}></div>
    </div>
  );
}

export default Test;

解決後のコード

test.js
import React, { useState, useEffect } from "react";
import { db } from "../firebase.js";

const Test = () => {
  const [imgStyle, setImgStyle] = useState([]);

  useEffect(() => {

   db.collection("test").get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        const docVal = doc.data();
        setImgStyle(oldForm => [...oldForm,
          {backgroundImage: `url(${docVal.imgUrl})`}
        ]);
      });
    }).catch(function(error) {
      console.log("Error getting document:", error);
    });

  }, []);

  return (
    <div>
      <div className="reportBefore" style={imgStyle[0]}></div>
    </div>
  );
}

export default Test;

まとめ

読みのみで変更はできないので、useStateでオブジェクトを扱う際は追加のイメージを忘れずに持っておくことが必要です。