Home > Enterprise >  Argument of type 'string' is not assignable to parameter of type 'ChangeEvent<HTML
Argument of type 'string' is not assignable to parameter of type 'ChangeEvent<HTML

Time:09-22

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

Here is the error

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>
  );

  • Related