#reactjs #typescript #sorting #compiler-errors
#reactjs #typescript #сортировка #ошибки компилятора
Вопрос:
У меня проблема с сортировкой таблицы в компоненте react. Проблема связана с typescript, и он выделяет аргумент и отображает ошибку следующего содержания: ‘Аргумент типа ‘ (name1: string, name2: string) => number’ не может быть присвоен параметру типа ‘(a: Element, b: Element) => number’. Типы параметров ‘name1’ и ‘a’ несовместимы. Тип ‘Element’ нельзя присвоить типу ‘string’.
Мой родительский компонент:
const SearchWithDropdown: React.FC = () => {
const [countries, setCountries] = useState<Array<Country>>([])
const [value, setValue] = useState('')
const [filteredCountries, setFilteredCountries] = useState<Array<Country>>([])
const [isVisible, setIsVisible] = useState(false)
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target
setValue(value)
changeResultVisibility(value)
}
const changeResultVisibility = (value: string) => {
setIsVisible(value.length >= 3)
}
useEffect(() => {
const fetchMyAPI = async () => {
let response = await fetch(url)
const json = await response.json()
setCountries(json)
}
fetchMyAPI()
}, [])
useEffect(() => {
if (value.length >= 3 amp;amp; countries.length > 0) {
setFilteredCountries(
countries
.filter((el: Country) => el.name.toLowerCase().includes(value))
)
}
}, [value, countries])
console.log(filteredCountries)
return (
<div>
<input type="text" placeholder="Search..." value={value} onChange={handleChange}></input>
{isVisible ? (
filteredCountries.length > 0 ? (
<DropdownList filteredCountries={filteredCountries} value={value} />
) : (
<div>Not found!</div>
)
) : null}
</div>
)
}
И дочерний компонент:
interface DropdownListProps {
filteredCountries: Country[]
value: string
}
function sortData (name1: string, name2: string): number {
name1 = name1.toLowerCase()
name2 = name2.toLowerCase()
return name1 > name2 ? 1 : name2 > name1 ? -1 : 0
}
const DropdownList: React.FC<DropdownListProps> = ({ filteredCountries, value }) => {
const renderData = () =>
filteredCountries
.map((el) => (
<DropdownItem key={el.name}>
{reactStringReplace(el.name, value, (match: string, i: number) => (
<strong key={i}>{match}</strong>
))}
</DropdownItem>
))
.sort(sortData)
return <div>{renderData()}</div>
}
И мой файл d.ts:
export interface Country {
name: string
}
Я пытался решить, изменив объявление в файле d.ts, но это звучит немного глупо. Я новичок в TS, поэтому, возможно, мое предположение о сортировке в этом месте неверно. Возможно, это должно быть после метода filter в родительском компоненте … хм..
Большое спасибо за помощь!
Комментарии:
1. Компилятор точно сообщает вам, в чем проблема.
sortData
ожидает два строковых параметра, однако вашеfilteredCountries.map
выражение возвращает массивJSX.Element
объектов, а затем вы пытаетесь отсортировать этот массив. Исходя из моей головы, я бы посоветовал вам просто попытаться переместить.sort
перед.map
и посмотреть, как это происходит2. … поэтому вместо того, чтобы
filteredCountries.map().sort()
пытатьсяfilteredCountries.sort().map()
3. Правильно! Спасибо! Это решило проблему 😉
Ответ №1:
Похоже, что ваша функция сортировки получает элемент, потому что вы изменяете свой массив countries с помощью метода map и возвращаете массив выпадающих элементов. Поэтому я бы посоветовал выполнить сортировку перед передачей данных компонентам DropdownItem.
Также элемент filteredCountries является объектом с именем свойства ({name: string}), поэтому ваша функция сортировки получит объект и должна извлечь из него свойство name
function sortData (c1: Country, c2: Country): number {