#javascript #reactjs #typescript #react-hooks #typescript2.0
Вопрос:
Я создаю раскрывающийся компонент, но typescript выдает несколько ошибок в случаях options.map и selectedOption.title:
import React, { useRef,useState, useEffect } from "react";
import useToggle from '../hooks/useToggle';
import useDetectOutsideClick from '../hooks/useOutsideClick';
import "./select.scss";
interface TProduct {
title?: string;
options?: [];
getDropDownValue?: any;
}
interface TOption {
title?: string;
value?: string;
id?: any;
}
const Select = (props: TProduct) => {
let { title, options, getDropDownValue } = props;
const dropdownRef = useRef(null);
const [visibility, setVisibility] = useDetectOutsideClick(dropdownRef, false);
const [selectedOption, setSelectedOption] = useState<TOption>({});
return (
<div
className="base-select"
ref={dropdownRef}
onClick={e => {
setVisibility(!visibility);
}}
>
<div className="selected-option">
<span
title={
selectedOption === ""
? title
: selectedOption.title
}
>
{selectedOption === ""
? title
: selectedOption.title.length <= 20
? selectedOption.title
: selectedOption amp;amp; selectedOption.title amp;amp; `${selectedOption.title.slice(0, 20)}`}
</span>
</div>
{visibility amp;amp; (
<div className="options">
<ul>
{options
.map((option) => (
<li
key={index}
className={
selectedOption amp;amp; selectedOption === option
? "active-option"
: ''
}
onClick={() => {
setSelectedOption(option);
getDropDownValue(option);
}
}
>
{option.title}
</li>
))}
</ul>
</div>
)}
</div>
);
};
export default Select
Таким образом, как зацикливание элементов списка, так и заголовки выдают ошибку для типа опций и выбранных опций.Объект типа заголовка, возможно, не определен
Что не так и как это можно исправить?
Комментарии:
1. добавьте a
?
, чтобы проверить доступность объекта перед доступом к собственности. такие какpossiblyUndefinedObject?.title
2. Я также предлагаю обновить
amp;amp;
оператор доselectedOption?.id === option.id
, u не может соответствовать объекту, например,selectedOption
другому, использующему==
или===
.3. @SultanH. он показывает ошибку в key= {index}, а также в option.title в цикле. Я полагаю ? отметки не решают проблему. Если это возможно, не могли бы вы, пожалуйста, ответить на вопрос?
Ответ №1:
Это можно исправить, безопасно набрав свой option
и selectedOption
с ?
оператором из TS и добавив index
в свою options.map
функцию обратного вызова.
<div
className="base-select"
ref={dropdownRef}
onClick={e => {
setVisibility(!visibility);
}}
>
<div className="selected-option">
<span
title={
selectedOption === ""
? title
: selectedOption?.title
}
>
{selectedOption === ""
? title
: selectedOption?.title?.length <= 20
? selectedOption?.title
: selectedOption?.title amp;amp; `${selectedOption?.title?.slice(0, 20)}`}
</span>
</div>
{visibility amp;amp; (
<div className="options">
<ul>
{options
.map((option, index) => (
<li
key={index}
className={
selectedOption?.id === option?.id
? "active-option"
: ""
}
onClick={() => {
setSelectedOption(option);
getDropDownValue(option);
}}
>
{option?.title}
</li>
))}
</ul>
</div>
)}
</div>
Я настоятельно рекомендую строго вводить реквизиты любого создаваемого вами компонента react, который наиболее удобен здесь.
например:
type CustomSelectProps = {
options?: Array<TOption>;
title?: string;
getDropDownValue?: (option: TOption) => void;
}
const Select: React.FC<CustomSelectProps> = (props) => {
// ...component content...
}
Комментарии:
1. Он по-прежнему показывает ошибку для .заголовок } > {Выбранная опция === «» ? заголовок : Выбранная опция? .название. длина .название : Выбранная опция? .название amp;amp;
${selectedOption?.title.slice(0, 20)}
}2. Обновлено, @NewTechLover просто применяет там ту же концепцию.. так
selectedOption
как , возможноundefined
, в этом случае само название было бы, таким образом, мы бы делали что-то подобноеundefined.slice
, что там невозможно.