之前分享过一篇《如何优雅地在 React 中使用TypeScript,看这一篇就够了!》,文中介绍了React和TypeScript搭配使用的一些常见用法。其中第四部分介绍了在React的事件处理中如何定义事件类型,下面来通过一些简单的 Demo (每个 Demo 后面都有 CodeSandBox 的在线体验地址)看看如何在 React + TypeScrip 中处理常见的事件!

目录:
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事件:

  • button按钮的onClick事件;
  • 任意元素的的onClick事件。

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [clickedButton, setClickedButton] = useState("");
  5. const buttonHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  6. event.preventDefault();
  7. const button: HTMLButtonElement = event.currentTarget;
  8. setClickedButton(button.name);
  9. };
  10. return (
  11. <div className="container">
  12. <form>
  13. <button onClick={buttonHandler} className="button" name="button 1">
  14. Button 1
  15. </button>
  16. <button onClick={buttonHandler} className="button" name="button 2">
  17. Button 2
  18. </button>
  19. <button onClick={buttonHandler} className="button" name="button 3">
  20. Button 3
  21. </button>
  22. </form>
  23. <h1>
  24. {clickedButton !== "" ? `点击了 ${clickedButton}` : "没有点击任何按钮"}
  25. </h1>
  26. </div>
  27. );
  28. };
  29. export default App;

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

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

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

  1. import React from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. // 当 container 被点击时,触发该事件
  5. const divClickedHandler = (event: React.MouseEvent<HTMLDivElement>) => {
  6. const div = event.currentTarget;
  7. console.log(
  8. "ElementName: ", div.tagName,
  9. "Width: ", div.clientWidth,
  10. "Height: ", div.clientHeight
  11. );
  12. };
  13. // 当 h1 被点击时,触发该事件
  14. const headingClickedHandler = (event: React.MouseEvent<HTMLHeadingElement>) => {
  15. event.stopPropagation();
  16. const heading = event.currentTarget;
  17. console.log(
  18. "ElementName: ", heading.tagName,
  19. "Width: ", heading.clientWidth,
  20. "Height: ", heading.clientHeight
  21. );
  22. };
  23. // 当图片被点击时,触发该事件
  24. const imgClickedHandler = (event: React.MouseEvent<HTMLImageElement>) => {
  25. event.stopPropagation();
  26. const img = event.currentTarget;
  27. console.log(
  28. "ElementName: ", img.tagName,
  29. "Width: ", img.clientWidth,
  30. "Height: ", img.clientHeight
  31. );
  32. };
  33. return (
  34. <div className="container" onClick={divClickedHandler}>
  35. <h1 onClick={headingClickedHandler}>Hello World</h1>
  36. <img
  37. src="https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.png"
  38. alt="111"
  39. onClick={imgClickedHandler}
  40. />
  41. </div>
  42. );
  43. };
  44. export default App;

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

  1. event.stopPropagation();

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

2. onChange

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [selectedOption, setSelectedOption] = useState<String>();
  5. const selectChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  6. const value = event.target.value;
  7. setSelectedOption(value);
  8. };
  9. return (
  10. <div className="container">
  11. <select onChange={selectChange} className="select">
  12. <option selected disabled>
  13. 选择一个
  14. </option>
  15. <option value="blue">Blue</option>
  16. <option value="red">Red</option>
  17. <option value="green">Green</option>
  18. <option value="yellow">Yellow</option>
  19. </select>
  20. {selectedOption && <h2 className="result">{selectedOption}</h2>}
  21. </div>
  22. );
  23. };
  24. export default App;

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

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

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. interface Item {
  4. id: number;
  5. name: string;
  6. price: number;
  7. }
  8. const PRODUCTS: Item[] = [
  9. {
  10. id: 1,
  11. name: "Apple",
  12. price: 1
  13. },
  14. {
  15. id: 2,
  16. name: "Book",
  17. price: 5
  18. },
  19. {
  20. id: 3,
  21. name: "Banana",
  22. price: 0.5
  23. },
  24. {
  25. id: 4,
  26. name: "Table",
  27. price: 200
  28. }
  29. ];
  30. const App: React.FunctionComponent = () => {
  31. const [query, setQuery] = useState("");
  32. const [result, setResult] = useState<Item[] | undefined>();
  33. // 当 input 的内容改变时触发
  34. const inputHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
  35. const enteredName = event.target.value;
  36. setQuery(enteredName);
  37. };
  38. // 点击搜索时触发
  39. const search = () => {
  40. const foundItems = PRODUCTS.filter((item) =>
  41. item.name.toLowerCase().includes(query.toLowerCase())
  42. );
  43. setResult(foundItems);
  44. };
  45. return (
  46. <div className="container">
  47. <div className="wrapper">
  48. <input
  49. value={query}
  50. onChange={inputHandler}
  51. placeholder="输入要搜索的商品名称"
  52. className="input"
  53. />
  54. <button onClick={search}>搜索</button>
  55. </div>
  56. <div className="search-result">
  57. {result && result.length > 0 ? (
  58. result.map((item) => (
  59. <li key={item.id} className="item">
  60. <span className="item-id">{item.id}</span>
  61. <span className="item-name">{item.name}</span>
  62. <span className="item-price">{item.price}¥</span>
  63. </li>
  64. ))
  65. ) : (
  66. <h2>没有找到!</h2>
  67. )}
  68. </div>
  69. </div>
  70. );
  71. };
  72. export default App;

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

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

3. onScroll

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

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const DUMMY_DATA = Array.from({ length: 100 }, (x, i) => {
  4. return {
  5. id: i,
  6. title: `Item ${i}`
  7. };
  8. });
  9. const App: React.FunctionComponent = () => {
  10. const [progress, setProgress] = useState(0);
  11. // 当元素发生滚动时触发该事件
  12. const scrollHandler = (event: React.UIEvent<HTMLDivElement>) => {
  13. const containerHeight = event.currentTarget.clientHeight;
  14. const scrollHeight = event.currentTarget.scrollHeight;
  15. const scrollTop = event.currentTarget.scrollTop;
  16. setProgress(((scrollTop + containerHeight) / scrollHeight) * 100);
  17. };
  18. return (
  19. <>
  20. <div className="container" onScroll={scrollHandler}>
  21. <div className="list">
  22. {DUMMY_DATA.map((item) => (
  23. <div className="item" key={item.id}>
  24. {item.title}
  25. </div>
  26. ))}
  27. </div>
  28. </div>
  29. <div className="progressBar">
  30. <div className="progressValue" style={{ width: `${progress}%` }}></div>
  31. </div>
  32. <p className="text">{progress.toFixed(2)}%</p>
  33. </>
  34. );
  35. };
  36. export default App;

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

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

4. onSubmit

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [term, setTerm] = useState("");
  5. const submitForm = (event: React.FormEvent<HTMLFormElement>) => {
  6. // 防止页面重新加载
  7. event.preventDefault();
  8. alert(term);
  9. };
  10. return (
  11. <div className="container">
  12. <form onSubmit={submitForm}>
  13. <input
  14. value={term}
  15. onChange={(e) => setTerm(e.target.value)}
  16. type="text"
  17. className="input"
  18. />
  19. <button type="submit" className="btn">
  20. 提交
  21. </button>
  22. </form>
  23. </div>
  24. );
  25. };
  26. export default App;

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

  1. event.preventDefault();

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

5. onCopy、onCut、onPaste

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

  • onCopy事件:在用户复制元素或元素的内容(如文本、图像)时触发;
  • onPaste事件:在用户在元素中粘贴一些内容时触发;
  • onCut事件:在用户剪切元素的内容时发生,此事件主要用于 input (type=”text”) 和 textarea 元素。

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [text, setText] = useState("hello world");
  5. // 复制:onCopy
  6. const copyHandler = (event: React.ClipboardEvent<HTMLInputElement>) => {
  7. event.currentTarget.style.border = "3px solid green";
  8. };
  9. // 剪切:onCut
  10. const cutHandler = (event: React.ClipboardEvent<HTMLInputElement>) => {
  11. event.currentTarget.style.border = "3px solid orange";
  12. event.currentTarget.style.backgroundColor = "yellow";
  13. event.currentTarget.disabled = true;
  14. setText("内容被剪切啦");
  15. };
  16. // 粘贴:onPaste
  17. const pasteHandler = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
  18. event.currentTarget.style.border = "5px solid purple";
  19. event.currentTarget.style.backgroundColor = "orange";
  20. event.currentTarget.value = event.clipboardData.getData("text").toUpperCase();
  21. event.preventDefault();
  22. };
  23. return (
  24. <div className="container">
  25. <input type="text" value={text} onCopy={copyHandler} onCut={cutHandler} />
  26. <hr />
  27. <p>在下方粘贴:</p>
  28. <textarea onPaste={pasteHandler} className="text-area"></textarea>
  29. </div>
  30. );
  31. };
  32. export default App;

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

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

6. onMouseOver、onMouseOut

onmouseoveronmouseout 是常用的两个鼠标事件:

  • onmouseover:在鼠标指针移动到指定的对象上时触发;
  • onmouseout:在鼠标指针移出指定的对象时触发。

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

  1. import React from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. // 当鼠标指针位于box上时,将触发此功能
  5. const boxMouseOverHandler = (event: React.MouseEvent<HTMLDivElement>) => {
  6. const box: HTMLDivElement = event.currentTarget;
  7. box.style.backgroundColor = "lightblue";
  8. };
  9. // 当鼠标指针移出box时,将触发此功能
  10. const boxMouseOutHandler = (event: React.MouseEvent<HTMLDivElement>) => {
  11. const box: HTMLDivElement = event.currentTarget;
  12. box.style.backgroundColor = "lightgreen";
  13. };
  14. // 当鼠标指针位于输入框上时,将触发此功能
  15. const inputMouseOverHandler = (event: React.MouseEvent<HTMLInputElement>) => {
  16. const input: HTMLInputElement = event.currentTarget;
  17. input.style.backgroundColor = "lime";
  18. };
  19. //当鼠标指针移出输入框时,将触发此功能
  20. const inputMouseOutHandler = (event: React.MouseEvent<HTMLInputElement>) => {
  21. const input: HTMLInputElement = event.currentTarget;
  22. input.style.backgroundColor = "white";
  23. };
  24. //当鼠标指针位于按钮上时,将触发此功能
  25. const buttonMouseOverHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  26. const btn: HTMLButtonElement = event.currentTarget;
  27. btn.style.border = "3px solid red";
  28. btn.style.backgroundColor = "orange";
  29. };
  30. // 当鼠标指针移出按钮时,将触发此功能
  31. const buttonMouseOutHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  32. const btn: HTMLButtonElement = event.currentTarget;
  33. btn.style.border = "none";
  34. btn.style.backgroundColor = "yellow";
  35. };
  36. return (
  37. <div
  38. className="box"
  39. onMouseOver={boxMouseOverHandler}
  40. onMouseOut={boxMouseOutHandler}
  41. >
  42. <input
  43. onMouseOver={inputMouseOverHandler}
  44. onMouseOut={inputMouseOutHandler}
  45. placeholder="hello world"
  46. />
  47. <button
  48. onMouseOver={buttonMouseOverHandler}
  49. onMouseOut={buttonMouseOutHandler}
  50. >
  51. Button
  52. </button>
  53. </div>
  54. );
  55. };
  56. export default App;

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

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

7. onLoad、onError

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

  • onload:资源加载失败;
  • onerror:资源加载出错。

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

  1. import React from "react";
  2. import "./styles.css";
  3. const IMAGE ="https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.png";
  4. const FALLBACK_IMAGE ="https://resource-1255585089.cos.ap-beijing.myqcloud.com/222.png";
  5. const App: React.FunctionComponent = () => {
  6. const imageOnLoadHandler = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
  7. // 图片加载成功时,打印图片的地址,并添加类名 success
  8. console.log(event.currentTarget.src);
  9. if (event.currentTarget.className !== "error") {
  10. event.currentTarget.className = "success";
  11. }
  12. };
  13. const imageOnErrorHandler = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
  14. // 图片加载失败时,加载替代的图片,并添加类名 error
  15. event.currentTarget.src = FALLBACK_IMAGE;
  16. event.currentTarget.className = "error";
  17. };
  18. return (
  19. <div className="container">
  20. <img
  21. src={IMAGE}
  22. onLoad={imageOnLoadHandler}
  23. onError={imageOnErrorHandler}
  24. alt="111"
  25. />
  26. </div>
  27. );
  28. };
  29. export default App;

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

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

8. onkeydown、onkeypress、onkeyup

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

  • onKeyDown:在用户按下一个键盘按键时触发;
  • onKeyUp:在键盘按键被松开时触发;
  • onKeyPress:在键盘按键被按下并释放一个键时发生。在所有浏览器中 onkeypress 事件只能监听字母和数字,不能监听一些特殊按键(ALT、CTRL、SHIFT、ESC、箭头等)。监听一个用户是否按下按键请使用 onkeydown 事件,所有浏览器都支持 onkeydown 事件。

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

  1. onkeydown
  2. onkeypress
  3. onkeyup

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [enteredText, setEnteredText] = useState("");
  5. // onKeyDown 事件处理函数
  6. const keyDownHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
  7. if (event.code === "Enter") {
  8. alert(`输入内容:"${enteredText}"`);
  9. }
  10. };
  11. // onKeyUp 事件处理函数
  12. const keyUpHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
  13. if (event.code === "Escape") {
  14. const confirm = window.confirm("确定清除文本吗?");
  15. if (confirm) {
  16. setEnteredText("");
  17. }
  18. }
  19. };
  20. // onKeyPress 事件处理函数
  21. const keyPressHandler = (event: React.KeyboardEvent<HTMLInputElement>) => {
  22. //...
  23. };
  24. return (
  25. <div className="container">
  26. <input
  27. onKeyDown={keyDownHandler}
  28. onKeyUp={keyUpHandler}
  29. onKeyPress={keyPressHandler}
  30. type="text"
  31. className="text-input"
  32. value={enteredText}
  33. onChange={(e) => setEnteredText(e.target.value)}
  34. />
  35. </div>
  36. );
  37. };
  38. export default App;

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

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

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [left, setLeft] = useState(0);
  5. const [top, setTop] = useState(0);
  6. // onKeyDown 事件处理函数
  7. const keyDownHandler = (event: React.KeyboardEvent<HTMLDivElement>) => {
  8. console.log(event.code);
  9. if (event.code === "ArrowUp") {
  10. setTop((top) => top - 10);
  11. }
  12. if (event.code === "ArrowDown") {
  13. setTop((top) => top + 10);
  14. }
  15. if (event.code === "ArrowLeft") {
  16. setLeft((left) => left - 10);
  17. }
  18. if (event.code === "ArrowRight") {
  19. setLeft((left) => left + 10);
  20. }
  21. };
  22. return (
  23. <div className="container" tabIndex={0} onKeyDown={keyDownHandler}>
  24. <div className="box" style={{ top: top, left: left }}></div>
  25. </div>
  26. );
  27. };
  28. export default App;

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

9. onFocus、onBlur

  • onfocus:在元素获得焦点时被触发,适用于<input><select> 以及<a>标签;
  • onblur:在元素失去焦点时触发,常用于表单验证。

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

  1. import React, { useState } from "react";
  2. import "./styles.css";
  3. const App: React.FunctionComponent = () => {
  4. const [name, setName] = useState("");
  5. const [isValid, setIsValid] = useState(false);
  6. const [isFocus, setIsFocus] = useState(false);
  7. const [isBlur, setIsBlur] = useState(false);
  8. // 处理 input 的 onChange事件
  9. const changeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
  10. setName(event.target.value);
  11. };
  12. // 处理 input 的 onFocus 事件
  13. const focusHandler = (event: React.FocusEvent<HTMLInputElement>) => {
  14. setIsFocus(true);
  15. setIsBlur(false);
  16. console.log(event);
  17. };
  18. // 处理 input 的 onBlur 事件
  19. const blurHandler = (event: React.FocusEvent<HTMLInputElement>) => {
  20. setIsFocus(false);
  21. setIsBlur(true);
  22. if (name.match(/^[a-z][a-z\s]*$/i)) {
  23. setIsValid(true);
  24. } else {
  25. setIsValid(false);
  26. }
  27. console.log(event);
  28. };
  29. return (
  30. <div className="container">
  31. <input
  32. type="text"
  33. onFocus={focusHandler}
  34. onBlur={blurHandler}
  35. value={name}
  36. onChange={changeHandler}
  37. className="input"
  38. placeholder="请输入名字"
  39. />
  40. {isFocus && <span className="hint">只能输入字母和空格</span>}
  41. {isBlur && !isValid && <p className="error">输入格式错误</p>}
  42. {isBlur && isValid && <p className="success">输入正确</p>}
  43. </div>
  44. );
  45. };
  46. export default App;

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

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

10. onDragStart、onDrop、onDragOver

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

  • onDragStart:开始拖拽时触发,事件里利用dataTransfer保存拖拽元素的 classid
  • onDrop:元素放置时不断触发,事件里利用dataTransfer来获取所保存的数据,并进行业务处理。
  • onDragOver:在拖拽时不断触发,在其中取消默认行为可以保证该标签可以放置拖拽元素。 ```typescript import React, { useState } from “react”; import “./styles.css”;

const PHOTO_URL = “https://resource-1255585089.cos.ap-beijing.myqcloud.com/111.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} > 111

  1. <div
  2. className="box2"
  3. onDragStart={(event) => dragStartHandler(event, "黄色卡片")}
  4. draggable={true}
  5. ></div>
  6. <div className="box3" onDragOver={allowDrop} onDrop={dropHandler}>
  7. {content.endsWith(".png") ? (
  8. <img src={content} alt="" />
  9. ) : (
  10. <h2>{content}</h2>
  11. )}
  12. </div>
  13. </div>

); };

export default App;

  1. 可以看到,两个拖拽事件的事件对象类型都是 `DragEvent`。可以通过事件对象的 `dataTransfer` 来获取事件对象的属性。
  2. **在线体验:**[https://codesandbox.io/s/crazy-cloud-5jejr1](https://codesandbox.io/s/crazy-cloud-5jejr1?file=/src/App.tsx:0-1382)
  3. <a name="SBABF"></a>
  4. ## 11. window.resize
  5. React 中是不支持直接定义 `onResize` 事件的。可以使用浏览器原生支持的 `window.resize` 事件,当浏览器窗口发生变化时会触发改事件。
  6. 可以使用以下两种方式之一来设置事件处理函数:
  7. ```javascript
  8. window.resize = myHandlerFunction;
  9. window.addEventListener('resize', myHandlerFunction);

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

  1. useEffect(() => {
  2. window.onresize = myHandlerFunction;
  3. }, []);
  4. useEffect(() => {
  5. window.addEventListener('resize', myHandlerFunction);
  6. }, []);

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

  1. import React, { useState, useEffect, FunctionComponent } from "react";
  2. import "./styles.css";
  3. interface Size {
  4. width: number;
  5. height: number;
  6. }
  7. const App: FunctionComponent = () => {
  8. const [size, setSize] = useState<Size>();
  9. const resizeHanlder = () => {
  10. const width = window.innerWidth;
  11. const height = window.innerHeight;
  12. setSize({
  13. width: width,
  14. height: height,
  15. });
  16. };
  17. useEffect(() => {
  18. window.onresize = resizeHanlder;
  19. }, []);
  20. return (
  21. <div
  22. className="container"
  23. style={{
  24. backgroundColor:
  25. !size || size.width <= 500
  26. ? "white"
  27. : size && size.width <= 700
  28. ? "green"
  29. : "orange",
  30. }}
  31. >
  32. {size && (
  33. <>
  34. <h2>Width: {size.width}</h2>
  35. <h2>Height: {size.height}</h2>
  36. </>
  37. )}
  38. </div>
  39. );
  40. };
  41. export default App;

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