添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

React event types

The React event system is a wrapper around the browser’s native event system. TypeScript types for this event system are available in the @types/react npm package. These types can be used to strongly-type event parameters. Some of the common ones are:

  • ChangeEvent<T>
  • KeyboardEvent<T>
  • MouseEvent<T>
  • FormEvent<T>
  • These types are all derived from SyntheticEvent<T> .

    All the event types are generic and take in the type for the element that raised the event. For example, MouseEvent<HTMLButtonElement> could be used for the parameter type for a button click handler.

    Inline event handlers

    If the event handler is implemented inline in the JSX element, it is automatically strongly-typed. Consider the example below:

    <input
      type="text"
      value={criteria}
      onChange={(e) =>
        setCriteria(e.currentTarget.value)
    

    TypeScript is able to infer the type of e to be ChangeEvent<HTMLInputElement>. So, we get nice autocompletion when we reference e:

    🏃 Play with the code

    Named event handlers

    The typing is a little more tricky when a named function is used for the event handler. Consider the example below:

    function Searchbox() {
      const [criteria, setCriteria] = React.useState(
      const handleChange = (e) => {    setCriteria(e.currentTarget.value);  };  return (
        <input
          type="text"
          value={criteria}
          onChange={handleChange}
    

    TypeScript infers the type of the e parameter in handleChange to be any. So, no type checking will occur when e is referenced in the handler implementation.

    Not good!

    We can use a type annotation to define the type of e explicitly. What type should e be set to? Well, a neat tip is to hover over the event handler prop to find out:

    So, the type is ChangeEvent<HTMLInputElement>. So, a strongly-typed version of the handleChange event handler is as follows:

    const handleChange = (
      e: React.ChangeEvent<HTMLInputElement>) => {
      setCriteria(e.currentTarget.value);
    

    Neat!

    🏃 Play with the code

    Cross element event handlers

    What about event handlers that handle events from multiple elements? Consider the example below:

    const handleChange = (fieldName: string) => (e) => {  ...};
    return (
      <input
        type="text"
        placeholder="Enter your name"
        value={values.name}
        onChange={handleChange("name")}  />
      <textarea
        placeholder="Enter some notes"
        value={values.notes}
        onChange={handleChange("notes")}  />
    

    The e parameter in the event handler is of type any at the moment.

    We can use the ChangeEvent type for e, but what element type do we pass into this generic type? The event handler is handling events for two different elements - HTMLInputElement and HTMLTextAreaElement. We can use the union type, HTMLInputElement | HTMLTextAreaElement, for these elements. So, a strongly-typed event handler is as follows:

    const handleChange = (fieldName: string) => (
      e: React.ChangeEvent<    HTMLInputElement | HTMLTextAreaElement  >) => {
    

    We can also narrow down the type for the fieldName if we have a type for all the field values. In this example the type of values is:

    type NameAndNotes = {
      name: string;
      notes: string;
    

    So, we can improve the typing of fieldName with the keyof keyword as follows:

    const handleChange = (fieldName: keyof NameAndNotes) => ( ... ) => ...

    Neat!