-3

before I use only nextJs everything is good to go but after I try to use recoil and I try to assign new value to array object by using .map() but the error show up

Cannot assign to read only property 

Here is my example Array object

  const [allData, setAllData] = useRecoilState(
    allDataStatte
  );

Here is example state AllData

const allData = [ { id:1, value:"test1" }, { id:2, value:"test2" } ]

Here is my code

const edit = (listId, value) => {
  allData.map((data) => {
    if (data.id === listId) {
      data.value = value;
    }
  });
};

example I want to call edit funcion like this

edit(1,"newTitle1")

I want my new allData output look like this

const data = [
  {
    id:1,
    value:"newTitle1"
  },
  {
    id:2,
    value:"test2"
  }
]

I have read someone told that I have to use .slice() to create new object but still not use how to use slice with an array object

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Akw
  • 91
  • 2
  • 11
  • I don't use Recoil, but you shouldn't be trying to directly modify state objects like that (which apparently it actively prevents, which is handy.) Also, [`map` is not for just looping](https://thenewtoys.dev/blog/2021/04/17/misusing-map/). You probably do want `map` here, but unlike above, you want to actually **use** its return value. ("Probably" because I don't use Recoil.) – T.J. Crowder Apr 22 '21 at 07:45

2 Answers2

3

Here is what you need to do,

const [allData, setAllData] = useRecoilState(allDataState);

const edit = (listId : number, value : string) => {
  let newAllData = allData.map((data) => {
    let newData = {...data};
    if (data.id === listId) {
      newData.value = value;
    }
    return newData;
  });
  setAllData (newAllData);
};
edit(1, 'new value 1');

Noticed, newAllData is a new array. Also newData is a new object constructed from data.

tigerpaw
  • 135
  • 4
-1

it's because of atom in recoil you have to re create object array and then setState again by using _clondeep or slice

Akw
  • 91
  • 2
  • 11