ReactJS — ошибка типа: не удается присвоить свойству ‘имя’ объекта ‘#’ только для чтения

#reactjs #typescript #react-state-management

#reactjs #typescript #управление состоянием реакции

Вопрос:

У меня есть массив объектов:

 var subcategories = [{name:'gloves', tag:'wool'}, {name:'boots', tag: 'leather'}]
  

Все, что я хочу сделать, это найти индекс объекта, чтобы изменить имя или тег. Я использую эту функцию:

 function setSubcat(val, index, lang){
   var newArr = []
   var obj = {
      'name': val
   }
   subcategories.map((val, i)=>{
      if(index === i){
         var newObj = Object.assign(val, obj)
         newArr.push(newObj)
      }
      newArr.push(val)
   })
   setSubcategories(newArr)
}
           
  

Ошибка возникает при var newObj = Object.assign(val, obj)

Я думал, что ошибка означает, что я не могу напрямую изменять состояние, и поэтому мне нужно сделать копию. Я думал, что отображение через subcategories и перенос его в локальный newArr означает, что я сделал копию массива. Но это не сработало, когда я хотел изменить значение object в нем, поэтому я использовал Object.assign, который, как я думал, будет глубоко копировать конкретный объект из массива, но он тоже не работает.

Чего мне здесь не хватает?

Комментарии:

1. Невозможно воспроизвести: typescriptlang.org/play ? #code/…

2. согласен; не могли бы вы опубликовать больше кода или пример игровой площадки? этот код хорош как есть.

3. Пожалуйста, не используйте map этот способ. Все будут читать этот код и думать: «Это ошибка? Мне нужно спросить его ….». map предназначен для преобразования каждого элемента, forEach предназначен для посещения каждого элемента.

4. Все еще работает с map правильно используемым: typescriptlang.org/play ? #code/…

5. @Lesiak это оно. Большое спасибо

Ответ №1:

Как указано в комментариях:

  • опубликованный вами код не показывает, как вы создали объект с неизменяемым свойством
  • вы можете создать новый объект и не использовать Object.assign, чтобы избавиться от ошибки
  • используйте map функцию более идиоматичным способом
 interface TaggedItem {
    name: string,
    tag: string
}
var subcategories = [{name:'gloves', tag:'wool'}, {name:'boots', tag: 'leather'}];

function setSubcat(val: string, index: number, _lang: any){
   var obj: Partial<TaggedItem> = {
      'name': val
   }
   var newArr: TaggedItem[] = subcategories.map((val, i)=>{
      if(index === i){
        return {
            ...val,
            ...obj
        } 
      } else {
        return {...val};
        // or return val; if you don't need a full copy
      }
   })
   console.log(newArr);
}

setSubcat('newName', 0, undefined);
  

Ссылка на игровую площадку

Комментарии:

1. Да, то, как я использовал map, не помогло. Это действительно здорово, еще раз спасибо.