У меня есть массив состояний, и когда пользователь нажимает на элемент, элемент должен быть добавлен в массив состояний. Я использую скрипт типа, интерфейс для модели данных.
Это код, который я использовал
this.setState(prevState => ({
this.state.activeItemList: [...prevState.activeItemList, newItem]
}))
Интерфейс
interface IState { activeItemList?: IItem[] | null; }
Это правильный путь?





Это, безусловно, а правильный способ, да, и я бы сказал, что сегодня это, вероятно, идиоматический способ. Вы делаете обе важные вещи:
setState, иИдеально!
Вы также можете использовать concat вместо распространения:
this.setState(prevState => ({
this.state.activeItemList: prevState.activeItemList.concat(newItem)
}))
но опять же, ваш путь, вероятно, идиоматичен в современном мире. Кроме того, если бы newItem был массивом (например, activeItemList был задуман как массив массивов), concat распространил бы его, что было бы нехорошо.
На самом деле, я бы написал так
this.setState(prevState => ({
...prevState,
activeItemList: [...prevState.activeItemList, newItem]
}))
С текущим определением IState это означает то же самое, но если IState когда-либо изменится, я готов. Кроме того, в коде подчеркивается, что все, что он делает, это добавляет newItem, а не стирает что-либо еще.
Удаление я бы реализовал как:
this.setState(prevState => ({
...prevState,
activeItemList: prevState.activeItemList.filter(item => item !== oldItem)
}))
Извините, исправил некоторые опечатки.
Во-первых, вам нужно проверить, не был ли массив нулевым или неопределенным, тогда вы можете добавить новый элемент в существующий массив, иначе создайте массив с помощью newItem.
this.setState((prevState) => ({
...prevState,
activeItemList: prevState.activeItemList ? [...prevState.activeItemList, newItem] : [newItem],
}));
Похоже, вы проверяете, существует ли prevState.activeItemList или нет, не проверяя, массив это или нет. Лучшим подходом будет запуск state = { activeItemList: [] }, который изначально гарантирует, что это массив, вместо проверки, верно @kwdowik?
Конечно, вы можете назначить пустой массив для activeItemList в конструкторе, как вы написали, но я предполагаю, что машинописный текст по-прежнему будет концентрировать внимание на том, что activeItemList может быть неопределенным или нулевым. @DaniVijay
Я получаю эту ошибку:
Argument of type '(prevState: Readonly<IState>) => { activeItemList: (IItem | undefined)[]; }' is not assignable to parameter of type 'IState | ((prevState: Readonly<IState>, props: Readonly<IProps>) => IState | Pick<IState, "activeItemList"> | null) | Pick<IState, "activeItemList"> | null'.