React / Redux, вызов метода из модели выдает TypeError - PullRequest
0 голосов
/ 11 апреля 2020

Я пытаюсь запустить formatAddress из модели, чтобы отобразить адрес в отформатированном виде, но он выдает TypeError при каждом вызове этого метода.

Component

export const PostRow: React.FC<Props> = ({ index, userIndex }) => {
    const dispatch = useDispatch()
    const { name, username, email, formatAddress } = useSelector((state: RootState) => state.users[userIndex])
    console.log(formatAddress())

Редуктор


export const userReducer: Reducer<UserState, UserActions> = (state: UserState = [], action: UserActions): UserState => {
    switch (action.type) {
        case UserActionTypes.GET_ALL_USERS:
            return action.payload.map((user: UserResponseDTO) => (new User(user)))
        default:
            return state
    }
}

Модель

export class User {
    public id: number
    public name: string
    public username: string
    public email: string
    public address: UserAdress
    public phone: string
    public website: string
    public company: UserCompany

    constructor(userDTO: UserResponseDTO) {
        this.id = userDTO.id
        this.name = userDTO.name
        this.username = userDTO.username
        this.email = userDTO.email
        this.address = userDTO.address
        this.phone = userDTO.phone
        this.website = userDTO.website
        this.company = userDTO.company
    }

    formatAddress() {
        return `${this.address.street}. ${this.address.city} - ${this.address.zipcode}`
    }
}

Возврат

TypeError: Cannot read property 'address' of undefined

1 Ответ

0 голосов
/ 11 апреля 2020

Для обычных функций значение this определяется тем, как вызывается функция. Поскольку вы сохранили formatAddress в переменной, а затем вызвали его с кодом formatAddress(), он вызывается без какого-либо контекста. В результате, this по умолчанию не определено (или в нестрогом режиме для объекта окна).

Один из вариантов - изменить способ его вызова. Если вы сохраните пользовательский объект и затем вызовете user.formatAddress(), тогда this будет установлен равным пользователю:

const user = useSelector((state: RootState) => state.users[userIndex]);
console.log(user.formatAddress());

В качестве альтернативы, вы можете привязать formatAddress к пользователю. Это создает новую функцию, значение которой this постоянно запекается в:

constructor(userDTO: UserResponseDTO) {
  this.id = userDTO.id
  // ... etc
  this.company = userDTO.company
  this.formatAddress = this.formatAddress.bind(this);
}

Или используйте функцию стрелки, поскольку они получают свои this из того, что this было равно, когда функция стрелки был создан. Поскольку вы используете машинопись, вы можете использовать следующий синтаксис:

export class User {
  // ... stuff omitted
  constructor(userDTO: UserResponseDTO) {
    //...
  }

  formatAddress = () => {
    return `${this.address.street}. ${this.address.city} - ${this.address.zipcode}`
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...