#reactjs #typescript
#reactjs #typescript
Вопрос:
У меня есть состояние реакции, которое представляет собой массив объектов, и я добавляю к нему объект в методе setState. Объекты добавляются правильно.
Теперь, когда я пытаюсь получить доступ к объекту в какой-либо другой функции, я не могу получить доступ к свойству object . Я вижу на консоли, что объект существует со свойствами. Я проверил другие подобные вопросы по stackoverflow, которые связаны с асинхронными вызовами, но мой не подпадает под это.
Я создал массив объектов, подобных этому,
interface ResultState{
....
localArray : object[];
}
Инициализируем его значением null в конструкторе.
И добавление к нему объекта, например,
localArray : this.state.localArray.concat(Items1)
Мой вывод на консоль :
localArray -> [{}]
0:
name: 'abcd'
roll_num: 10
address: [{...}]
0: {Street: 'abcdefgh', aptnum: 1}
Теперь я хочу получить доступ к адресу объекта.
Мой код выглядит так,
const resultObject = this.state.localArray[0];
return resultObject.address;
Но я получаю сообщение об ошибке адрес свойства не существует для типа object.
когда я делаю console.log(typeof(resultObject)), появляется object .
в чем может быть причина этого?
Комментарии:
1. Какой результат
JSON.stringify(this.state.localArray[0])
? Я не уверен, но я думаю, что некоторые браузеры регистрируют ссылку на объект, поэтому, когда объект изменяется после регистрации, он также изменяет зарегистрированное значение2. Вывод выглядит следующим образом: {«name»:»abcd»,»roll_num»:10, «address»:»…»}
3. Просто чтобы быть уверенным: это регистрируется прямо перед назначением
resultObject
? И это то же самое, что и ведение журналаJSON.stringify(resultObject)
?4. да, для обоих. Я регистрирую его перед назначением resultObject и stringify resultObject также одинаковы.
5. Ибо
localArray: object[]
вы на самом деле используете тип «объект»? Убедитесь, что независимо от типа объекта, у него есть поле адреса define. Если у вас нет определенного типа, попробуйтеlocalArray: any[]
Ответ №1:
Я рад, что у вас получилось, но использование type any[]
не очень хорошо, потому что это говорит о том, что ваш массив может содержать что угодно. Что вы действительно хотите, так это чтобы typescript знал тип конкретных объектов в вашем массиве. Основываясь на том, что вы опубликовали, это должно быть что-то вроде:
interface Address {
Street: string;
aptnum: number;
}
interface Entry {
name: string;
roll_num: number;
address: Address[];
}
interface ResultState {
....
localArray: Entry[];
}
Таким образом, typescript знает, что элементы вашего массива являются объектами, но он также знает, какие свойства допустимы и какие типы для каждого свойства.
Комментарии:
1. Но проблема в том, что этот объект поступает из вызова api, и структура json может иметь несколько вариантов. Итак, что следует делать в этом случае?
2. Знаете ли вы, какой из вариантов вы получите при выполнении вызова? Если это так, вы должны использовать generics для определения типа во время вызова. Если вы не знаете, как выглядит ответ, пока не увидите его, вы бы использовали то, что называется дискриминируемым объединением.
3. Другой способ подумать: «какой минимум мне нужен прямо сейчас для этой функции?» Вместо того, чтобы вводить весь ответ, просто введите части, которые вы используете. Вы получаете доступ
resultObject.address
, поэтому ожидаете, что каждый объект в вашем массиве имеетaddress
свойство, иначе это не имеет смысла. Таким образом, вы можете сказатьlocalArray: {address: Address[]}[]
, что это нормально, если объект имеет больше, чем просто это свойство, но будут и должны быть ошибки, если вы не можете быть уверены, что объекты содержат это свойство. Цель ошибок typescript — избежать потенциальных ошибок во время выполнения.4. Да, мое
address
определение будет меняться в зависимости от некоторых критериев. Будет 5 вариантов. Так что, возможно, я могу использовать дженерики в этом случае.
Ответ №2:
Да, это было из-за типа массива. После изменения его на localArray: any[]
, это сработало!