文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React + TypeScript:如何处理常见事件?

2024-11-30 12:23

关注

目录:

  1. onClick
  2. onChange
  3. onScroll
  4. onSubmit
  5. onCopy、onCut、onPaste
  6. onMouseOver、onMouseOut
  7. onLoad、onError
  8. onkeydown、onkeypress、onkeyup
  9. onFocus、onBlur
  10. onDragStart、onDrop、onDragOver
  11. window.resize

1. onClick

onClick 是用的最多的事件之一,这里主要列举两种类型的 onClick 事件:

下面先来看看按钮的 onClick 事件,当点击按钮时,在页面显示按钮的名称:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [clickedButton, setClickedButton] = useState("");

  const buttonHandler = (event: React.MouseEvent) => {
    event.preventDefault();
    const button: HTMLButtonElement = event.currentTarget;
    setClickedButton(button.name);
  };

  return (
    
); }; export default App;

可以看到,onClick 事件的事件处理对象的类型都定义为了 MouseEvent,其中传入的参数为绑定事件的元素的类型。可以通过事件对象的 currentTarget 属性来获取点击元素的属性。

在线体验:https://codesandbox.io/s/dawn-feather-8gofq1

再来看看任意元素的 onClick事件,点击一个元素时,在控制台打印点击元素的类型、长度、宽度:

import React from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  // 当 container 被点击时,触发该事件
  const divClickedHandler = (event: React.MouseEvent) => {
    const div = event.currentTarget;
    console.log(
      "ElementName: ", div.tagName,
      "Width: ", div.clientWidth,
      "Height: ", div.clientHeight
    );
  };

  // 当 h1 被点击时,触发该事件
  const headingClickedHandler = (event: React.MouseEvent) => {
    event.stopPropagation();

    const heading = event.currentTarget;
    console.log(
      "ElementName: ", heading.tagName,
      "Width: ", heading.clientWidth,
      "Height: ", heading.clientHeight
    );
  };

  // 当图片被点击时,触发该事件
  const imgClickedHandler = (event: React.MouseEvent) => {
    event.stopPropagation();
    
    const img = event.currentTarget;
    console.log(
      "ElementName: ", img.tagName,
      "Width: ", img.clientWidth,
      "Height: ", img.clientHeight
    );
  };

  return (
    
); }; export default App;

可以看到,onClick 事件的事件处理对象的类型都定义为了 MouseEvent,其中传入的参数为绑定事件的元素的类型。需要注意,在任意元素上添加点击事件时,会触发事件冒泡,比如上面的例子,当点击是图片或者h1标签时就会导致其父元素div的点击事件触发。可以使用下面的代码来避免默认事件:

event.stopPropagation();

在线体验:https://codesandbox.io/s/serverless-glade-g41upi

2. onChange

下面来看看 onChange 事件,先来看 select 元素的 onChange 事件的例子,当选中元素时,选中元素的值会显示在页面上:

import React, { useState } from "react";
import "./styles.css";

const App: React.FunctionComponent = () => {
  const [selectedOption, setSelectedOption] = useState();

  const selectChange = (event: React.ChangeEvent) => {
    const value = event.target.value;
    setSelectedOption(value);
  };

  return (
    
{selectedOption &&

{selectedOption}

}
); }; export default App;

可以看到,select 元素的 onSelect 的事件对象类型为 ChangeEvent,传入的参数为 select 元素的类型。可以通过 target 属性来获取 select选中的值。

在线体验:https://codesandbox.io/s/frosty-lichterman-33fpky

input 元素的 onChange 事件的例子,在输入框中输入内容,点击搜索按钮,在页面显示搜索结果:

import React, { useState } from "react";
import "./styles.css";

interface Item {
  id: number;
  name: string;
  price: number;
}

const PRODUCTS: Item[] = [
  {
    id: 1,
    name: "Apple",
    price: 1
  },
  {
    id: 2,
    name: "Book",
    price: 5
  },
  {
    id: 3,
    name: "Banana",
    price: 0.5
  },
  {
    id: 4,
    name: "Table",
    price: 200
  }
];

const App: React.FunctionComponent = () => {
  const [query, setQuery] = useState("");
  const [result, setResult] = useState();

  // 当 input 的内容改变时触发
  const inputHandler = (event: React.ChangeEvent) => {
    const enteredName = event.target.value;
    setQuery(enteredName);
  };

  // 点击搜索时触发
  const search = () => {
    const foundItems = PRODUCTS.filter((item) =>
      item.name.toLowerCase().includes(query.toLowerCase())
    );
    setResult(foundItems);
  };

  return (
    
{result && result.length > 0 ? ( result.map((item) => (
  • {item.id} {item.name} {item.price}¥
  • )) ) : (

    没有找到!

    )}
    ); }; export default App;

    可以看到,这里input 的事件处理对象的类型为 ChangeEvent。要想获取输入的值需要从事件对象的 target 属性中获取。

    在线体验:https://codesandbox.io/s/pedantic-murdock-lejmg6

    3. onScroll

    onScroll 事件在元素的滚动条被滚动时触发。

    下面来看一个例子,当元素发生滚动时,计算滚动了多少的元素,从而计算页面滚动进度的百分比值,并显示在页面上:

    import React, { useState } from "react";
    import "./styles.css";
    
    const DUMMY_DATA = Array.from({ length: 100 }, (x, i) => {
      return {
        id: i,
        title: `Item ${i}`
      };
    });
    
    const App: React.FunctionComponent = () => {
      const [progress, setProgress] = useState(0);
      
      // 当元素发生滚动时触发该事件
      const scrollHandler = (event: React.UIEvent) => {
        const containerHeight = event.currentTarget.clientHeight;
        const scrollHeight = event.currentTarget.scrollHeight;
        const scrollTop = event.currentTarget.scrollTop;
        setProgress(((scrollTop + containerHeight) / scrollHeight) * 100);
      };
    
      return (
        <>
          
    {DUMMY_DATA.map((item) => (
    {item.title}
    ))}

    {progress.toFixed(2)}%

    ); }; export default App;

    可以看到,onScroll 事件的事件对象类型定义为了:React.UIEvent,参数为绑定事件的元素的类型。可以通过事件对象的 currentTarget 属性来获取页面滚动的相关值。

    在线体验:https://codesandbox.io/s/competent-hellman-qh7non

    4. onSubmit

    下面来看看表单的 onSubmit 事件,该事件在表单提交时触发:

    import React, { useState } from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      const [term, setTerm] = useState("");
    
      const submitForm = (event: React.FormEvent) => {
        // 防止页面重新加载
        event.preventDefault();
        alert(term);
      };
    
      return (
        
    setTerm(e.target.value)} type="text" className="input" />
    ); }; export default App;

    表单提交事件的时间对象类型为 FormEvent。需要注意,为了防止页面在表单的 onSubmit事件触发时重新加载,需要调用:

    event.preventDefault();

    在线体验:https://codesandbox.io/s/condescending-danny-e1eerd

    5. onCopy、onCut、onPaste

    下面来看看常见的复制、剪切、粘贴这三个时间:

    下面来看一个例子,当进行复制、剪切、粘贴时,给操作的元素加上一些样式:

    import React, { useState } from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      const [text, setText] = useState("hello world");
    
      // 复制:onCopy
      const copyHandler = (event: React.ClipboardEvent) => {
        event.currentTarget.style.border = "3px solid green";
      };
    
      // 剪切:onCut
      const cutHandler = (event: React.ClipboardEvent) => {
        event.currentTarget.style.border = "3px solid orange";
        event.currentTarget.style.backgroundColor = "yellow";
        event.currentTarget.disabled = true;
        setText("内容被剪切啦");
      };
    
      // 粘贴:onPaste
      const pasteHandler = (event: React.ClipboardEvent) => {
        event.currentTarget.style.border = "5px solid purple";
        event.currentTarget.style.backgroundColor = "orange";
        event.currentTarget.value = event.clipboardData.getData("text").toUpperCase();
        event.preventDefault();
      };
    
      return (
        

    在下方粘贴:

    ); }; export default App;

    可以看到,这三个事件的事件处理对象的类型都定义为了 ClipboardEvent,其中传入的参数为绑定事件的元素的类型。可以通过 currentTarget 属性来获取事件对象的属性。

    在线体验:https://codesandbox.io/s/sleepy-keldysh-w5vemj

    6. onMouseOver、onMouseOut

    onmouseover 和 onmouseout 是常用的两个鼠标事件:

    下面来看一个例子,当鼠标在元素上和移出元素时给元素添加不同的样式:

    import React from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      // 当鼠标指针位于box上时,将触发此功能
      const boxMouseOverHandler = (event: React.MouseEvent) => {
        const box: HTMLDivElement = event.currentTarget;
        box.style.backgroundColor = "lightblue";
      };
    
      // 当鼠标指针移出box时,将触发此功能
      const boxMouseOutHandler = (event: React.MouseEvent) => {
        const box: HTMLDivElement = event.currentTarget;
        box.style.backgroundColor = "lightgreen";
      };
    
      // 当鼠标指针位于输入框上时,将触发此功能
      const inputMouseOverHandler = (event: React.MouseEvent) => {
        const input: HTMLInputElement = event.currentTarget;
        input.style.backgroundColor = "lime";
      };
    
      //当鼠标指针移出输入框时,将触发此功能
      const inputMouseOutHandler = (event: React.MouseEvent) => {
        const input: HTMLInputElement = event.currentTarget;
        input.style.backgroundColor = "white";
      };
    
      //当鼠标指针位于按钮上时,将触发此功能
      const buttonMouseOverHandler = (event: React.MouseEvent) => {
        const btn: HTMLButtonElement = event.currentTarget;
        btn.style.border = "3px solid red";
        btn.style.backgroundColor = "orange";
      };
    
      // 当鼠标指针移出按钮时,将触发此功能
      const buttonMouseOutHandler = (event: React.MouseEvent) => {
        const btn: HTMLButtonElement = event.currentTarget;
        btn.style.border = "none";
        btn.style.backgroundColor = "yellow";
      };
    
      return (
        
    ); }; export default App;

    可以看到,这两个事件的事件处理对象的类型都定义为了 MouseEvent,其中传入的参数为绑定事件的元素的类型。可以通过事件对象的 currentTarget 来获取事件对象的属性。

    在线体验:https://codesandbox.io/s/nervous-cloud-5r6d6p

    7. onLoad、onError

    onLoad 和 onError 是页面外部资源加载相关的两个相关事件:

    下面来看一个例子, 当图片成功时给它添加类名 success,加载失败时添加类型 error,并更换为备用图片的URL:

    import React from "react";
    import "./styles.css";
    
    const IMAGE ="https://www.528045.com/file/upload/202411/30/5em2fousc0x.png";
    const FALLBACK_IMAGE ="https://www.528045.com/file/upload/202411/30/v2vt2ab0nmt.png";
    
    const App: React.FunctionComponent = () => {
      const imageOnLoadHandler = (event: React.SyntheticEvent) => {
        // 图片加载成功时,打印图片的地址,并添加类名 success
        console.log(event.currentTarget.src);
        if (event.currentTarget.className !== "error") {
          event.currentTarget.className = "success";
        }
      };
    
      const imageOnErrorHandler = (event: React.SyntheticEvent) => {
        // 图片加载失败时,加载替代的图片,并添加类名 error
        event.currentTarget.src = FALLBACK_IMAGE;
        event.currentTarget.className = "error";
      };
    
      return (
        
    ); }; export default App;

    可以看到,这两个事件的事件处理对象的类型都定义为了 SyntheticEvent,其中传入的第一个参数为绑定事件的元素的类型。可以通过事件对象的 currentTarget 属性来获取事件对象的属性。

    在线体验:https://codesandbox.io/s/determined-tamas-rjwjoq

    8. onkeydown、onkeypress、onkeyup

    下面来看几个常见的键盘事件:

    这三个事件的执行顺序如下:

    1. onkeydown
    2. onkeypress
    3. onkeyup

    来看一个例子,按下ESC键可以清除已经输入的文本,按下Enter键可以弹出已经输入的文本:

    import React, { useState } from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      const [enteredText, setEnteredText] = useState("");
    
      // onKeyDown 事件处理函数
      const keyDownHandler = (event: React.KeyboardEvent) => {
        if (event.code === "Enter") {
          alert(`输入内容:"${enteredText}"`);
        }
      };
    
      // onKeyUp 事件处理函数
      const keyUpHandler = (event: React.KeyboardEvent) => {
        if (event.code === "Escape") {
          const confirm = window.confirm("确定清除文本吗?");
    
          if (confirm) {
            setEnteredText("");
          }
        }
      };
    
      // onKeyPress 事件处理函数
      const keyPressHandler = (event: React.KeyboardEvent) => {
        //...
      };
    
      return (
        
    setEnteredText(e.target.value)} />
    ); }; export default App;

    这三个事件的事件对象类型都是 KeyboardEvent。可以通过事件对象的 code属性获取按下的键盘键值。

    在线体验:https://codesandbox.io/s/prod-sky-txwzgd

    再来看一个简单的例子,通过在键盘上按下上下左右键使得盒子在页面上移动:

    import React, { useState } from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      const [left, setLeft] = useState(0);
      const [top, setTop] = useState(0);
    
      // onKeyDown 事件处理函数
      const keyDownHandler = (event: React.KeyboardEvent) => {
        console.log(event.code);
        if (event.code === "ArrowUp") {
          setTop((top) => top - 10);
        }
    
        if (event.code === "ArrowDown") {
          setTop((top) => top + 10);
        }
    
        if (event.code === "ArrowLeft") {
          setLeft((left) => left - 10);
        }
    
        if (event.code === "ArrowRight") {
          setLeft((left) => left + 10);
        }
      };
    
      return (
        
    ); }; export default App;

    在线体验:https://codesandbox.io/s/hungry-meninsky-zhkbzb

    9. onFocus、onBlur

    下面来看一个例子,在输入框中输入内容,输入过程中保存输入的值, 当输入完成,失去输入焦点时,对输入内容进行校验:

    import React, { useState } from "react";
    import "./styles.css";
    
    const App: React.FunctionComponent = () => {
      const [name, setName] = useState("");
      const [isValid, setIsValid] = useState(false);
      const [isFocus, setIsFocus] = useState(false);
      const [isBlur, setIsBlur] = useState(false);
    
      // 处理 input 的 onChange事件
      const changeHandler = (event: React.ChangeEvent) => {
        setName(event.target.value);
      };
    
      // 处理 input 的 onFocus 事件
      const focusHandler = (event: React.FocusEvent) => {
        setIsFocus(true);
        setIsBlur(false);
        console.log(event);
      };
    
      // 处理 input 的 onBlur 事件
      const blurHandler = (event: React.FocusEvent) => {
        setIsFocus(false);
        setIsBlur(true);
    
        if (name.match(/^[a-z][a-z\s]*$/i)) {
          setIsValid(true);
        } else {
          setIsValid(false);
        }
        console.log(event);
      };
    
      return (
        
    {isFocus && 只能输入字母和空格} {isBlur && !isValid &&

    输入格式错误

    } {isBlur && isValid &&

    输入正确

    }
    ); }; export default App;

    这里两个事件的事件对象类型都是 FocusEvent,传入的参数是 input 元素的类型。

    在线体验:https://codesandbox.io/s/spring-moon-roegc5

    10. onDragStart、onDrop、onDragOver

    拖拽操作在HTML5 是作为标准的一部分。能够使用HTML5所支持的事件和属性来实现拖拽操作。下面是三个常用的拖拽事件:

    import React, { useState } from "react";
    import "./styles.css";
    
    const PHOTO_URL = "https://www.528045.com/file/upload/202411/30/5em2fousc0x.png";
    
    const App: React.FunctionComponent = () => {
      const [content, setContent] = useState("Drop Something Here");
    
      // 开始拖拽时触发改事件
      const dragStartHandler = (event: React.DragEvent, data: string) => {
        event.dataTransfer.setData("text", data);
      };
    
      // 在放置时触发该事件
      const dropHandler = (event: React.DragEvent) => {
        event.preventDefault();
        const data = event.dataTransfer.getData("text");
        setContent(data);
      };
    
      // 使得第三个盒子可以放下
      const allowDrop = (event: React.DragEvent) => {
        event.preventDefault();
      };
    
      return (
        
    dragStartHandler(event, PHOTO_URL)} draggable={true} >
    dragStartHandler(event, "黄色卡片")} draggable={true} >
    {content.endsWith(".png") ? ( ) : (

    {content}

    )}
    ); }; export default App;

    可以看到,两个拖拽事件的事件对象类型都是 DragEvent。可以通过事件对象的 dataTransfer 来获取事件对象的属性。

    在线体验:https://codesandbox.io/s/crazy-cloud-5jejr1

    11. window.resize

    在 React 中是不支持直接定义 onResize 事件的。可以使用浏览器原生支持的 window.resize 事件,当浏览器窗口发生变化时会触发改事件。

    可以使用以下两种方式之一来设置事件处理函数:

    window.resize = myHandlerFunction;
    
    window.addEventListener('resize', myHandlerFunction);

    在 React 中,要在浏览器窗口大小发生变化时重新渲染组件,可以使用 useStatehook 来实现:

    useEffect(() => {
      window.onresize = myHandlerFunction;
    }, []);
    
    useEffect(() => {
      window.addEventListener('resize', myHandlerFunction);
    }, []);

    下面来看一个例子,在改变浏览器窗口的大小时,页面实时显示浏览器窗口的长度和宽度,并在不同宽度时显示不同的背景色:

    import React, { useState, useEffect, FunctionComponent } from "react";
    import "./styles.css";
    
    interface Size {
      width: number;
      height: number;
    }
    
    const App: FunctionComponent = () => {
      const [size, setSize] = useState();
    
      const resizeHanlder = () => {
        const width = window.innerWidth;
        const height = window.innerHeight;
    
        setSize({
          width: width,
          height: height,
        });
      };
    
      useEffect(() => {
        window.onresize = resizeHanlder;
      }, []);
    
      return (
        
    {size && ( <>

    Width: {size.width}

    Height: {size.height}

    )}
    ); }; export default App;

    在线体验:https://codesandbox.io/s/async-leaf-m62ixj

    12. 备忘录

    常见的 Event 事件对象如下:

    常见的元素类型如下:

    来源:前端充电宝内容投诉

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    软考中级精品资料免费领

    • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

      难度     813人已做
      查看
    • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

      难度     354人已做
      查看
    • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

      难度     318人已做
      查看
    • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

      难度     435人已做
      查看
    • 2024年上半年系统架构设计师考试综合知识真题

      难度     224人已做
      查看

    相关文章

    发现更多好内容

    猜你喜欢

    AI推送时光机
    位置:首页-资讯-后端开发
    咦!没有更多了?去看看其它编程学习网 内容吧
    首页课程
    资料下载
    问答资讯