#javascript #reactjs #typescript #react-hooks
Вопрос:
Я переписываю свое старое приложение, написанное на React JavaScript, в React Typescript. В моем старом приложении код, который я пытаюсь повторно использовать, работал отлично, но TS это не нравится, и я не уверен, почему — я также впервые использую TS.
Я экспортирую свой тип данных:
export type CartItemType = {
.....
id: number;
name: string;
.....
}
И получение моих карт и данных с помощью крючков
const [cartItems, setCartItems] = useState([] as CartItemType[]);
const { data, isLoading, error } = useQuery<CartItemType[]>(
'products',
getProducts
);
Я сопоставляю данные, как обычно
data?.map((item) => {
return (
......
)}
Теперь каждый из моих объектов данных имеет разные варианты цветов, и я хотел бы иметь возможность переключаться между ними.
Это мой подход:
function handleColorChange(e) {
e.preventDefault();
let newData = [...data];
let changedItem = {
...data.find((i) => i.name === selectedData.name),
};
let changedItemIndex = data.findIndex(
(i) => i.name === selectedData.name
);
changedItem.chair.selected = e.target.value;
newData[changedItemIndex] = changedItem;
setSelectedColor(newData);
}
Чтобы объяснить приведенный выше код, я пытаюсь обрабатывать каждое изменение цвета, где selectedData
указаны только данные о выбранном продукте и chair.selected
значение цвета по умолчанию для конкретного продукта.
Я сопоставляю все цвета конкретного продукта с моим объектом данных
{Object.values(selectedData.chair.colors).map(
(key) => {
return (
<ItemButtonChair hex={key.hex} name={key.name} image={key}
click={handleColorChange}
></ItemButtonChair>
);})}
ItemButtonChair изготовлен мной на заказ
function ItemButtonChair(props) {
let colorHeaderClassName = `selected ${props.click}`;
return (
<input
type="button"
value={props.name}
name={props.name}
onClick={props.click}
className={colorHeaderClassName}
style={{
backgroundColor: props.hex,
color: props.hex,
}}
/>
);
}
Когда я пытаюсь запустить этот подход, я обнаруживаю ошибку Type 'CartItemType[] | undefined' must have a '[Symbol.iterator]()' method that returns an iterator.
, я пытался найти в Google, как это исправить, но, похоже, каждый случай с этой ошибкой очень обычен, и я просто не понимаю, почему TS это не нравится.
Ответ №1:
Ошибка типа на самом деле говорит вам о проблеме: тип data
is CartItemType[] | undefined
, поэтому он может быть undefined
, который вы не можете повторить. Хотя, поскольку у вас нет отслеживания или указания на него, я не знаю, что ...data
его вызывает и есть ли у него типовая защита или что-то в этом роде.
Если вы уверены data
, что на данный момент он существует, вы можете использовать ...data!
, чтобы сказать TypeScript «Я уверен, что это не null
/ undefined
«.
Комментарии:
1. Спасибо @KelvinSchoofs, ошибка указывает
data
наhandleColorChange
функцию. Я не знаю, как они могут быть неопределенными, так как я сопоставляю их и получаю свои объекты нормально. Я уже пробовал использовать...data!
, но это все еще кажется неправильным, с тех порchangedItem.chair.selected
он недокормлен…и я действительно не знаю, почему2. Ты звонишь
handleColorChange
изнутри карты? TypeScript не понимает, чтоhandleColorChange
он вызывается только тогда, когдаdata
установлен, поэтому он возвращается к... | undefined
функции. Измененияdata
вdata!
пределах этой функции должно быть достаточно. Что-то подобное может произойтиchangedItem.chair.selected
и с вами . Если вы уверены, что эти поля существуют, вы можете сделать, напримерchangedItem.chair!.selected
.
Ответ №2:
Я нашел решение, которое работает, вероятно, это не очень хорошая практика, чтобы делать это таким образом, поэтому я не буду отмечать это как решение, но оно работает!
Таким образом, в основном вместо одного состояния я создаю больше для каждого объекта, который у меня есть.
selectedColor1
, selectedColor2
, ……
И в handleColorChange
настройке функции для каждого состояния:
setSelectedColor1(newData[0]);
setSelectedColor2(newData[1]);
............
Я могу достичь того, что мне было нужно с помощью этого подхода, и цвета каждого объекта обновляются по щелчку мыши.