Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot assign to read only property 'props' of #<Object> error when trying to change React state

Here is my code :

import React, { useState, useEffect } from 'react';
import { useCountriesQuery } from '../store/apis/userApi';

const  CountryCmp = () => {

  const {data} = useCountriesQuery('FR')

  const [countryArray, setCountryArray] = useState(null)

  useEffect(() => {
    if(data){
      setCountryArray(data.countries) // data.countries = [ { "selected": false, "value": "Afghanistan" }, { "selected": false, "value": "Afrique du Sud" }... { "selected": false, "value": "Allemagne" }, { "selected": True, "value": "France" }]
    }
  }, [data])
  
  const [selectedCountry, setSelectedCountry] = useState('France')
  
  const updateSelectedCountry = (value) => {
    setSelectedCountry(value)
    let clonedCountryArray = [...countryArray]

    clonedCountryArray.map(item => {
      if(item.selected === true){
        item.selected =  false
      }
      return item
    })
    clonedCountryArray.map(item => {
      if(item.value === value){
        item.selected =  true   
         
      }
      return item 
    })
    console.log('countries', clonedCountryArray)
    setCountryArray(clonedCountryArray)
  }
  
  
 return <>
          {countryArray && <div className="pp-cons" >
            <div className="col_form_full" >
              <div>
                <span data-ppui="true">{selectedCountry}</span>
                <div>
                  <ul >
                      {countryArray.map((item,id) => {
                        return <li onClick={() => updateSelectedCountry(item.value)} key={id} >
                                  <p >
                                      <span className={"pp-"+(item.selected ? '_strong' : '')} > {item.value} </span>
                                    
                                  </p>
                              </li>})}
                  </ul>
              </div>
              </div>
            </div>
          </div>}
        </> 
}

export default CountryCmp;

Here data are fetched correctly from REST API through RTK Query (useCountriesQuery).

When I click to invoke updateSelectedCountry, I got this error :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Cannot assign to read only property 'selected' of object '#<Object>'
TypeError: Cannot assign to read only property 'selected' of object '#<Object>'

I thought countryArray was the problem, so I cloned it to not avail.

I don’t understand why. Please help!

>Solution :

The map function creates a new array, but the objects inside it are still references to the original objects. Since you are modifying the objects within the cloned array directly, it can lead to issues.

You can create a deep copy of the countryArray to ensure that the objects inside are also cloned. You can use libraries like lodash for deep cloning or use a custom deep clone function.

const updateSelectedCountry = (value) => {
  setSelectedCountry(value);

  let clonedCountryArray = [...countryArray];

  clonedCountryArray = clonedCountryArray.map((item) => ({ ...item }));

  clonedCountryArray.forEach((item) => {
    item.selected = item.value === value;
  });

  console.log('countries', clonedCountryArray);
  setCountryArray(clonedCountryArray);
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading