I'm just starting to learn typescript, so I decided to make a custom dropdown menu, but I ran into this problem. How to fix this problem?
import React, { useState } from 'react'
const DropDown = () => {
const platforms = ["Platform_1","Platform_2","Platform_3"]
const [drop, setDrop] = useState<boolean>(false)
const [name, setName] = useState<string | null>('All Platforms')
const changeSelect = (e: React.ChangeEvent<HTMLLIElement>) => {
setName(e.target.textContent)
setDrop(false)
}
return (
<div>
<div className="filter">
<div className="filter-name" onClick={() => setDrop(!drop)}>{name}</div>
{
drop ?
<ul>
{platforms.map((option) =>
<li onClick={e => changeSelect(option)}>{option}</li>
)}
</ul>
:
null
}
</div>
</div>
)
}
export default DropDown
CodePudding user response:
This is happening because you are passing the strings from the string array platforms
to changeSelect
, which takes an event of type React.ChangeEvent<HTMLLIElement>
as an argument and not string.
Additionally, you should use React.MouseEvent<HTMLLIElement>
type for your event if you are going to use onClick
. Depending on your editor, you may be able to find out what the type React expects; for example in VSCode holding Ctrl and hovering over onClick
will show (onClick?: MouseEventHandler<T> | undefined;
above the usual tooltip, telling you that you should use React.MouseEventHandler<T>
where T
is the html element.
Here's my revision of the code inside DropDown
:
const platforms = ["Platform_1", "Platform_2", "Platform_3"];
const [drop, setDrop] = useState<boolean>(false);
const [name, setName] = useState<string | null>("All Platforms");
const changeSelect = (e: React.MouseEvent<HTMLLIElement>) => { //changed type of `e` to React.MouseEvent<HTMLLIElement>
setName(e.currentTarget.textContent); // Changed from e.target to e.currentTarget
setDrop(false);
};
return (
<div>
<div className="filter">
<div className="filter-name" onClick={() => setDrop(!drop)}>
{name}
</div>
{drop ? (
<ul>
{platforms.map((option) => (
<li
onClick={(e: React.MouseEvent<HTMLLIElement>) => { //gave `e` type
changeSelect(e);
}}
>
{option}
</li>
))}
</ul>
) : null}
</div>
</div>
);