所有内置浏览器组件,例如 <div>,都支持一些通用的属性和事件。
参考
常见组件(例如 <div>)
<div className="wrapper">一些内容</div>属性
所有内置组件都支持这些特殊的 React 属性:
-
children:一个 React 节点(一个元素、字符串、数字、portal,一个空节点如null、undefined和布尔值,或其他 React 节点的数组)。指定组件内部的内容。当你使用 JSX 时,通常会通过嵌套标签(如<div><span /></div>)隐式指定children属性。 -
dangerouslySetInnerHTML:一个形如{ __html: '<p>some html</p>' }的对象,内部包含原始 HTML 字符串。它会覆盖 DOM 节点的innerHTML属性,并在其中显示传入的 HTML。应极其谨慎地使用!如果其中的 HTML 不可信(例如基于用户数据),就有引入 XSS 漏洞的风险。阅读更多关于使用dangerouslySetInnerHTML的内容。 -
ref:来自useRef或createRef的 ref 对象,或一个ref回调函数,或用于 旧版 refs 的字符串。你的 ref 将填充为该节点的 DOM 元素。阅读更多关于使用 refs 操作 DOM 的内容。 -
suppressContentEditableWarning:一个布尔值。如果为true,则会抑制 React 在元素同时具有children和contentEditable={true}时显示的警告(这两者通常不能一起工作)。当你构建一个手动管理contentEditable内容的文本输入库时可使用此项。 -
suppressHydrationWarning:一个布尔值。如果你使用 服务端渲染,通常当服务端和客户端渲染出不同内容时会出现警告。在某些罕见情况下(如时间戳),要保证完全一致非常困难甚至不可能。如果将suppressHydrationWarning设为true,React 将不会就该元素的属性和内容不匹配发出警告。它只作用于一层深度,并且 предназначляется 作为一种逃生出口。不要过度使用它。阅读关于抑制 hydration 错误的内容。 -
style:一个包含 CSS 样式的对象,例如{ fontWeight: 'bold', margin: 20 }。类似于 DOM 的style属性,CSS 属性名需要写成camelCase,例如用fontWeight而不是font-weight。你可以传入字符串或数字作为值。如果传入数字,例如width: 100,React 会自动在值后追加px(“像素”),除非它是一个 无单位属性。我们建议仅在你事先不知道样式值的动态样式中使用style。在其他情况下,使用className应用普通 CSS 类会更高效。阅读更多关于className和style的内容。
所有这些标准 DOM 属性也都支持用于所有内置组件:
accessKey:一个字符串。指定该元素的键盘快捷键。通常不推荐使用。aria-*:ARIA 属性让你为该元素指定可访问性树信息。完整参考请参见 ARIA 属性。在 React 中,所有 ARIA 属性名都与 HTML 中完全相同。autoCapitalize:一个字符串。指定用户输入是否以及如何首字母大写。className:一个字符串。指定元素的 CSS 类名。阅读更多关于应用 CSS 样式的内容。contentEditable:一个布尔值。如果为true,浏览器允许用户直接编辑渲染出的元素。这用于实现像 Lexical. 这样的富文本输入库。如果你尝试向contentEditable={true}的元素传递 React 子元素,React 会发出警告,因为在用户编辑后 React 将无法更新其内容。data-*: 数据属性让你可以为元素附加一些字符串数据,例如data-fruit="banana"。在 React 中,它们并不常用,因为你通常会改为从 props 或 state 中读取数据。dir:'ltr'或'rtl'。指定元素的文本方向。draggable:一个布尔值。指定元素是否可拖拽。HTML 拖放 API 的一部分。enterKeyHint:一个字符串。指定虚拟键盘上回车键应显示的动作。htmlFor:一个字符串。对于<label>和<output>,可让你将标签与某个控件关联起来。与forHTML 属性 相同。React 使用标准 DOM 属性名(htmlFor),而不是 HTML 属性名。hidden:一个布尔值或字符串。指定元素是否应隐藏。id:一个字符串。指定该元素的唯一标识符,可用于稍后查找它或将其与其他元素关联。使用useId生成它,以避免多个相同组件实例之间的冲突。is:一个字符串。如果指定,组件将表现得像一个 自定义元素。inputMode:一个字符串。指定要显示的键盘类型(例如文本、数字或电话)。itemProp:一个字符串。指定该元素在结构化数据爬虫中代表哪个属性。lang:一个字符串。指定元素的语言。onAnimationEnd:一个AnimationEvent处理函数。在 CSS 动画完成时触发。onAnimationEndCapture:onAnimationEnd的一个在 捕获阶段。触发的版本。onAnimationIteration:一个AnimationEvent处理函数。在某次 CSS 动画迭代结束、下一次开始时触发。onAnimationIterationCapture:onAnimationIteration的一个在 捕获阶段。触发的版本。onAnimationStart:一个AnimationEvent处理函数。在 CSS 动画开始时触发。onAnimationStartCapture:onAnimationStart,但在 捕获阶段。触发。onAuxClick:一个MouseEvent处理函数。在点击非主按键指针按钮时触发。onAuxClickCapture:onAuxClick的一个在 捕获阶段。触发的版本。onBeforeInput:一个InputEvent处理函数。在可编辑元素的值被修改之前触发。React 目前还没有使用原生的beforeinput事件,而是尝试使用其他事件来进行 polyfill。onBeforeInputCapture:onBeforeInput的一个在 捕获阶段。触发的版本。onBlur:一个FocusEvent处理函数。在元素失去焦点时触发。与内置浏览器的blur事件不同,在 React 中onBlur事件会冒泡。onBlurCapture:onBlur的一个在 捕获阶段。触发的版本。onClick:一个MouseEvent处理函数。在指针设备的主按钮被点击时触发。onClickCapture:onClick的一个在 捕获阶段。触发的版本。onCompositionStart:一个CompositionEvent处理函数。在 输入法编辑器 开始新的组合会话时触发。onCompositionStartCapture:onCompositionStart的一个在 捕获阶段。触发的版本。onCompositionEnd:一个CompositionEvent处理函数。在 输入法编辑器 完成或取消一个组合会话时触发。onCompositionEndCapture:onCompositionEnd的一个在 捕获阶段。触发的版本。onCompositionUpdate:一个CompositionEvent处理函数。在 输入法编辑器 接收到新字符时触发。onCompositionUpdateCapture:onCompositionUpdate的一个在 捕获阶段。触发的版本。onContextMenu:一个MouseEvent处理函数。在用户尝试打开上下文菜单时触发。onContextMenuCapture:onContextMenu的一个在 捕获阶段。触发的版本。onCopy:一个ClipboardEvent处理函数。在用户尝试将内容复制到剪贴板时触发。onCopyCapture:onCopy的一个在 捕获阶段。触发的版本。onCut:一个ClipboardEvent处理函数。在用户尝试将内容剪切到剪贴板时触发。onCutCapture:onCut的一个在 捕获阶段。触发的版本。onDoubleClick:一个MouseEvent处理函数。在用户双击时触发。对应于浏览器的dblclick事件。onDoubleClickCapture:onDoubleClick的一个在 捕获阶段。触发的版本。onDrag:一个DragEvent处理函数。在用户拖动某物时触发。onDragCapture:onDrag的一个在 捕获阶段。触发的版本。onDragEnd:一个DragEvent处理函数。在用户停止拖动某物时触发。onDragEndCapture:onDragEnd的一个在 捕获阶段。触发的版本。onDragEnter:一个DragEvent处理函数。在拖拽内容进入有效放置目标时触发。onDragEnterCapture:onDragEnter的一个在 捕获阶段。触发的版本。onDragOver:一个DragEvent处理函数。在拖拽内容悬停于有效放置目标上时触发。你必须在这里调用e.preventDefault()才能允许放置。onDragOverCapture:onDragOver的一个在 捕获阶段。触发的版本。onDragStart:一个DragEvent处理函数。在用户开始拖动元素时触发。onDragStartCapture:onDragStart的一个在 捕获阶段。触发的版本。onDrop:一个DragEvent处理函数。在某物被放到有效放置目标上时触发。onDropCapture:onDrop的一个在 捕获阶段。触发的版本。onFocus:一个FocusEvent处理函数。在元素获得焦点时触发。与内置浏览器的focus事件不同,在 React 中onFocus事件会冒泡。onFocusCapture:onFocus的一个在 捕获阶段。触发的版本。onGotPointerCapture:一个PointerEvent处理函数。在元素以编程方式捕获指针时触发。onGotPointerCaptureCapture:onGotPointerCapture的一个在 捕获阶段。触发的版本。onKeyDown:一个KeyboardEvent处理函数。在按下按键时触发。onKeyDownCapture:onKeyDown的一个在 捕获阶段。触发的版本。onKeyPress:一个KeyboardEvent处理函数。已弃用。请改用onKeyDown或onBeforeInput。onKeyPressCapture:onKeyPress的一个在 捕获阶段。触发的版本。onKeyUp:一个KeyboardEvent处理函数。在按键释放时触发。onKeyUpCapture:onKeyUp的一个在 捕获阶段。触发的版本。onLostPointerCapture:一个PointerEvent处理函数。在元素停止捕获指针时触发。onLostPointerCaptureCapture:onLostPointerCapture的一个在 捕获阶段。触发的版本。onMouseDown:一个MouseEvent处理函数。在指针按下时触发。onMouseDownCapture:onMouseDown的一个在 捕获阶段。触发的版本。onMouseEnter:一个MouseEvent处理函数。在指针移入元素内部时触发。没有捕获阶段。相反,onMouseLeave和onMouseEnter会从离开的元素传播到进入的元素。onMouseLeave:一个MouseEvent处理函数。在指针移出元素外部时触发。没有捕获阶段。相反,onMouseLeave和onMouseEnter会从离开的元素传播到进入的元素。onMouseMove:一个MouseEvent处理函数。在指针改变坐标时触发。onMouseMoveCapture:onMouseMove的一个在 捕获阶段。触发的版本。onMouseOut:一个MouseEvent处理函数。在指针移出元素外部,或者移入其子元素时触发。onMouseOutCapture:onMouseOut的一个在 捕获阶段。触发的版本。onMouseUp:一个MouseEvent处理函数。在指针释放时触发。onMouseUpCapture:onMouseUp的一个在 捕获阶段。触发的版本。onPointerCancel:一个PointerEvent处理函数。当浏览器取消指针交互时触发。onPointerCancelCapture:onPointerCancel的一个在 捕获阶段。触发的版本。onPointerDown:一个PointerEvent处理函数。当指针变为活跃状态时触发。onPointerDownCapture:onPointerDown的一个在 捕获阶段。触发的版本。onPointerEnter:一个PointerEvent处理函数。在指针移入元素内部时触发。没有捕获阶段。相反,onPointerLeave和onPointerEnter会从离开的元素传播到进入的元素。onPointerLeave:一个PointerEvent处理函数。在指针移出元素外部时触发。没有捕获阶段。相反,onPointerLeave和onPointerEnter会从离开的元素传播到进入的元素。onPointerMove:一个PointerEvent处理函数。在指针改变坐标时触发。onPointerMoveCapture:onPointerMove的一个在 捕获阶段。触发的版本。onPointerOut:一个PointerEvent处理函数。在指针移出元素外部、指针交互被取消时,以及其他一些原因。触发。onPointerOutCapture:onPointerOut的一个在 捕获阶段。触发的版本。onPointerUp:一个PointerEvent处理函数。当指针不再处于活动状态时触发。onPointerUpCapture:onPointerUp的一个在 捕获阶段。触发的版本。onPaste:一个ClipboardEvent处理函数。在用户尝试从剪贴板粘贴内容时触发。onPasteCapture:onPaste的一个在 捕获阶段。触发的版本。onScroll:一个Event处理函数。在元素滚动时触发。此事件不会冒泡。onScrollCapture:onScroll的一个在 捕获阶段。触发的版本。onSelect:一个Event处理函数。在输入框等可编辑元素中的选区发生变化后触发。React 也扩展了onSelect事件,使其同样可用于contentEditable={true}元素。此外,React 还将其扩展为在空选区和编辑时触发(这可能会影响选区)。onSelectCapture:onSelect的一个在 捕获阶段。触发的版本。onTouchCancel:一个TouchEvent处理函数。在浏览器取消触摸交互时触发。onTouchCancelCapture:onTouchCancel的一个在 捕获阶段。触发的版本。onTouchEnd:一个TouchEvent处理函数。在一个或多个触点被移除时触发。onTouchEndCapture:onTouchEnd的一个在 捕获阶段。触发的版本。onTouchMove:一个TouchEvent处理函数。在一个或多个触点移动时触发。onTouchMoveCapture:onTouchMove的一个在 捕获阶段。触发的版本。onTouchStart:一个TouchEvent处理函数。在一个或多个触点被放置时触发。onTouchStartCapture:onTouchStart的一个在 捕获阶段。触发的版本。onTransitionEnd:一个TransitionEvent处理函数。在 CSS 过渡完成时触发。onTransitionEndCapture:onTransitionEnd的一个在 捕获阶段。触发的版本。onWheel:一个WheelEvent处理函数。在用户旋转滚轮按钮时触发。onWheelCapture:onWheel的一个在 捕获阶段。触发的版本。role:一个字符串。为辅助技术显式指定元素角色。slot:一个字符串。在使用 shadow DOM 时指定槽名称。在 React 中,通常通过将 JSX 作为 props 传入来实现等价模式,例如<Layout left={<Sidebar />} right={<Content />} />。spellCheck:一个布尔值或null。如果显式设为true或false,则启用或禁用拼写检查。tabIndex:一个数字。覆盖默认的 Tab 键行为。避免使用-1和0以外的值。title:一个字符串。指定元素的工具提示文本。translate:'yes'或'no'。传入'no'会将元素内容排除在翻译之外。
你也可以将自定义属性作为 props 传入,例如 mycustomprop="someValue"。这在与第三方库集成时很有用。自定义属性名必须是小写且不能以 on 开头。其值会被转换为字符串。如果传入 null 或 undefined,自定义属性会被移除。
这些事件只会在 <form> 元素上触发:
onReset:一个Event处理函数。在表单被重置时触发。onResetCapture:onReset的一个在 捕获阶段。触发的版本。onSubmit:一个Event处理函数。在表单被提交时触发。onSubmitCapture:onSubmit的一个在 捕获阶段。触发的版本。
这些事件只会在 <dialog> 元素上触发。与浏览器事件不同,它们在 React 中会冒泡:
onCancel:一个Event处理函数。在用户尝试关闭对话框时触发。onCancelCapture:onCancel的一个在 捕获阶段。触发的版本。onClose:一个Event处理函数。在对话框关闭时触发。onCloseCapture:onClose的一个在 捕获阶段。触发的版本。
这些事件只会在 <details> 元素上触发。与浏览器事件不同,它们在 React 中会冒泡:
onToggle:一个Event处理函数。在用户切换 details 时触发。onToggleCapture:onToggle的一个在 捕获阶段。触发的版本。
这些事件会在 <img>、<iframe>、<object>、<embed>、<link> 和 SVG <image> 元素上触发。与浏览器事件不同,它们在 React 中会冒泡:
onLoad:一个Event处理函数。在资源加载完成时触发。onLoadCapture:onLoad的一个在 捕获阶段。触发的版本。onError:一个Event处理函数。在资源无法加载时触发。onErrorCapture:onError的一个在 捕获阶段。触发的版本。
这些事件会在诸如 <audio> 和 <video> 等资源上触发。与浏览器事件不同,它们在 React 中会冒泡:
onAbort:一个Event处理函数。在资源尚未完全加载、但不是由于错误导致时触发。onAbortCapture:onAbort的一个在 捕获阶段。触发的版本。onCanPlay:一个Event处理函数。在有足够数据开始播放、但不足以在不缓冲的情况下播放到结尾时触发。onCanPlayCapture:onCanPlay的一个在 捕获阶段。触发的版本。onCanPlayThrough:一个Event处理函数。在有足够数据、很可能可以在无需缓冲直到结束的情况下开始播放时触发。onCanPlayThroughCapture:onCanPlayThrough的一个在 捕获阶段。触发的版本。onDurationChange:一个Event处理函数。在媒体时长更新时触发。onDurationChangeCapture:onDurationChange的一个在 捕获阶段。触发的版本。onEmptied:一个Event处理函数。在媒体变为空时触发。onEmptiedCapture:onEmptied的一个在 捕获阶段。触发的版本。onEncrypted:一个Event处理函数。在浏览器遇到加密媒体时触发。onEncryptedCapture:onEncrypted的一个在 捕获阶段。触发的版本。onEnded:一个Event处理函数。在播放因没有剩余内容可播放而停止时触发。onEndedCapture:onEnded的一个在 捕获阶段。触发的版本。onError:一个Event处理函数。在资源无法加载时触发。onErrorCapture:onError的一个在 捕获阶段。触发的版本。onLoadedData:一个Event处理函数。在当前播放帧加载完成时触发。onLoadedDataCapture:onLoadedData的一个在 捕获阶段。触发的版本。onLoadedMetadata:一个Event处理函数。在元数据加载完成时触发。onLoadedMetadataCapture:onLoadedMetadata的一个在 捕获阶段。触发的版本。onLoadStart:一个Event处理函数。在浏览器开始加载资源时触发。onLoadStartCapture:onLoadStart的一个在 捕获阶段。触发的版本。onPause:一个Event处理函数。在媒体暂停时触发。onPauseCapture:onPause的一个在 捕获阶段。触发的版本。onPlay:一个Event处理函数。在媒体不再暂停时触发。onPlayCapture:onPlay的一个在 捕获阶段。触发的版本。onPlaying:一个Event处理函数。在媒体开始或重新开始播放时触发。onPlayingCapture:onPlaying的一个在 捕获阶段。触发的版本。onProgress:一个Event处理函数。在资源加载期间周期性触发。onProgressCapture:onProgress的一个在 捕获阶段。触发的版本。onRateChange:一个Event处理函数。在播放速率变化时触发。onRateChangeCapture:onRateChange的一个在 捕获阶段。触发的版本。onResize:一个Event处理函数。在视频尺寸变化时触发。onResizeCapture:onResize的一个在 捕获阶段。触发的版本。onSeeked:一个Event处理函数。在一次 seek 操作完成时触发。onSeekedCapture:onSeeked的一个在 捕获阶段。触发的版本。onSeeking:一个Event处理函数。在一次 seek 操作开始时触发。onSeekingCapture:onSeeking的一个在 捕获阶段。触发的版本。onStalled:一个Event处理函数。在浏览器等待数据但一直未能加载时触发。onStalledCapture:onStalled的一个在 捕获阶段。触发的版本。onSuspend:一个Event处理函数。在加载资源被挂起时触发。onSuspendCapture:onSuspend的一个在 捕获阶段。触发的版本。onTimeUpdate:一个Event处理函数。在当前播放时间更新时触发。onTimeUpdateCapture:onTimeUpdate的一个在 捕获阶段。触发的版本。onVolumeChange:一个Event处理函数。在音量变化时触发。onVolumeChangeCapture:onVolumeChange的一个在 捕获阶段。触发的版本。onWaiting:一个Event处理函数。在因临时缺少数据而停止播放时触发。onWaitingCapture:onWaiting的一个在 捕获阶段。触发的版本。
注意事项
- 你不能同时传入
children和dangerouslySetInnerHTML。 - 某些事件(如
onAbort和onLoad)在浏览器中不会冒泡,但在 React 中会冒泡。
ref 回调函数
你可以向 ref 属性传入一个函数,而不是 ref 对象(例如 useRef 返回的那个)。
<div ref={(node) => {
console.log('Attached', node);
return () => {
console.log('Clean up', node)
}
}}>当 <div> DOM 节点被添加到屏幕上时,React 会用 DOM node 作为参数调用你的 ref 回调。当该 <div> DOM 节点被移除时,React 会调用回调返回的清理函数。
只要你传入的是一个不同的 ref 回调,React 也会调用你的 ref 回调。在上面的示例中,(node) => { ... } 在每次渲染时都是不同的函数。当你的组件重新渲染时,之前的函数会以 null 作为参数被调用,而下一个函数会以 DOM 节点作为参数被调用。
参数
node:一个 DOM 节点。当 ref 绑定时,React 会将 DOM 节点传给你。除非你在每次渲染时都为ref回调传入相同的函数引用,否则该回调会在组件的每次重新渲染期间临时执行清理并重新创建。
返回值
- 可选
cleanup function:当ref被解绑时,React 会调用清理函数。如果ref回调没有返回函数,那么当ref被解绑时,React 会再次以null作为参数调用该回调。此行为将在未来版本中移除。
注意事项
- 当启用 Strict Mode 时,React 会在第一次真实的 setup 之前,额外执行一次仅开发环境可见的 setup+cleanup 循环。这是一个压力测试,用于确保你的清理逻辑能“镜像”你的 setup 逻辑,并停止或撤销 setup 所做的一切。如果这造成问题,请实现清理函数。
- 当你传入一个不同的
ref回调时,如果提供了清理函数,React 会调用之前回调的清理函数。如果没有定义清理函数,ref回调将以null作为参数被调用。下一个函数将以 DOM 节点作为参数被调用。
React 事件对象
你的事件处理函数将接收一个 React 事件对象。它有时也被称为“合成事件”。
<button onClick={e => {
console.log(e); // React 事件对象
}} />它遵循底层 DOM 事件相同的标准,但修复了一些浏览器不一致问题。
某些 React 事件不会直接映射到浏览器的原生事件。例如在 onMouseLeave 中,e.nativeEvent 会指向一个 mouseout 事件。具体映射并不是公共 API 的一部分,未来可能会改变。如果你出于某些原因需要底层浏览器事件,请从 e.nativeEvent 读取。
属性
React 事件对象实现了部分标准 Event 属性:
bubbles:一个布尔值。返回事件是否会通过 DOM 冒泡。cancelable:一个布尔值。返回事件是否可被取消。currentTarget:一个 DOM 节点。返回当前处理函数在 React 树中所附着的节点。defaultPrevented:一个布尔值。返回是否调用了preventDefault。eventPhase:一个数字。返回事件当前所处的阶段。isTrusted:一个布尔值。返回事件是否由用户发起。target:一个 DOM 节点。返回事件发生的节点(也可能是较远的子节点)。timeStamp:一个数字。返回事件发生的时间。
此外,React 事件对象还提供这些属性:
nativeEvent:一个 DOMEvent。原始浏览器事件对象。
方法
React 事件对象实现了部分标准 Event 方法:
preventDefault():阻止该事件的默认浏览器行为。stopPropagation():停止事件在 React 树中的传播。
此外,React 事件对象还提供这些方法:
isDefaultPrevented():返回一个布尔值,表示是否调用了preventDefault。isPropagationStopped():返回一个布尔值,表示是否调用了stopPropagation。persist():不用于 React DOM。对于 React Native,可调用它以在事件之后读取事件属性。isPersistent():不用于 React DOM。对于 React Native,返回是否已调用persist。
注意事项
currentTarget、eventPhase、target和type的值反映的是你的 React 代码所期望的值。在底层,React 会在根节点附加事件处理函数,但这不会反映在 React 事件对象中。例如,e.currentTarget可能与底层的e.nativeEvent.currentTarget不同。对于被 polyfill 的事件,e.type(React 事件类型)可能与e.nativeEvent.type(底层类型)不同。
AnimationEvent 处理函数
用于 CSS 动画 事件的事件处理函数类型。
<div
onAnimationStart={e => console.log('onAnimationStart')}
onAnimationIteration={e => console.log('onAnimationIteration')}
onAnimationEnd={e => console.log('onAnimationEnd')}
/>参数
e:一个带有以下额外AnimationEvent属性的 React 事件对象:
ClipboardEvent 处理函数
用于 Clipboard API 事件的事件处理函数类型。
<input
onCopy={e => console.log('onCopy')}
onCut={e => console.log('onCut')}
onPaste={e => console.log('onPaste')}
/>参数
-
e:一个带有以下额外ClipboardEvent属性的 React 事件对象:
CompositionEvent 处理函数
用于 输入法编辑器(IME) 事件的事件处理函数类型。
<input
onCompositionStart={e => console.log('onCompositionStart')}
onCompositionUpdate={e => console.log('onCompositionUpdate')}
onCompositionEnd={e => console.log('onCompositionEnd')}
/>参数
e:一个带有以下额外CompositionEvent属性的 React 事件对象:
DragEvent 处理函数
用于 HTML 拖放 API 事件的事件处理函数类型。
<>
<div
draggable={true}
onDragStart={e => console.log('onDragStart')}
onDragEnd={e => console.log('onDragEnd')}
>
拖拽源
</div>
<div
onDragEnter={e => console.log('onDragEnter')}
onDragLeave={e => console.log('onDragLeave')}
onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}
onDrop={e => console.log('onDrop')}
>
放置目标
</div>
</>参数
-
e:一个带有以下额外DragEvent属性的 React 事件对象:它还包括继承自
MouseEvent的属性:altKeybuttonbuttonsctrlKeyclientXclientYgetModifierState(key)metaKeymovementXmovementYpageXpageYrelatedTargetscreenXscreenYshiftKey
它还包括继承自
UIEvent的属性:
FocusEvent 处理函数
用于焦点事件的事件处理函数类型。
<input
onFocus={e => console.log('onFocus')}
onBlur={e => console.log('onBlur')}
/>参数
-
e:一个 React 事件对象,带有以下额外的FocusEvent属性:它还包含继承自
UIEvent的属性:
Event 处理函数
一种用于通用事件的事件处理函数类型。
参数
e:一个 React 事件对象,没有额外属性。
InputEvent 处理函数
一种用于 onBeforeInput 事件的事件处理函数类型。
<input onBeforeInput={e => console.log('onBeforeInput')} />参数
e:一个 React 事件对象,带有以下额外的InputEvent属性:
KeyboardEvent 处理函数
一种用于键盘事件的事件处理函数类型。
<input
onKeyDown={e => console.log('onKeyDown')}
onKeyUp={e => console.log('onKeyUp')}
/>参数
-
e:一个 React 事件对象,带有以下额外的KeyboardEvent属性:altKeycharCodecodectrlKeygetModifierState(key)keykeyCodelocalemetaKeylocationrepeatshiftKeywhich
它还包含继承自
UIEvent的属性:
MouseEvent 处理函数
一种用于鼠标事件的事件处理函数类型。
<div
onClick={e => console.log('onClick')}
onMouseEnter={e => console.log('onMouseEnter')}
onMouseOver={e => console.log('onMouseOver')}
onMouseDown={e => console.log('onMouseDown')}
onMouseUp={e => console.log('onMouseUp')}
onMouseLeave={e => console.log('onMouseLeave')}
/>参数
-
e:一个 React 事件对象,带有以下额外的MouseEvent属性:altKeybuttonbuttonsctrlKeyclientXclientYgetModifierState(key)metaKeymovementXmovementYpageXpageYrelatedTargetscreenXscreenYshiftKey
它还包含继承自
UIEvent的属性:
PointerEvent 处理函数
一种用于 指针事件 的事件处理函数类型。
<div
onPointerEnter={e => console.log('onPointerEnter')}
onPointerMove={e => console.log('onPointerMove')}
onPointerDown={e => console.log('onPointerDown')}
onPointerUp={e => console.log('onPointerUp')}
onPointerLeave={e => console.log('onPointerLeave')}
/>参数
-
e:一个 React 事件对象,带有以下额外的PointerEvent属性:它还包含继承自
MouseEvent的属性:altKeybuttonbuttonsctrlKeyclientXclientYgetModifierState(key)metaKeymovementXmovementYpageXpageYrelatedTargetscreenXscreenYshiftKey
它还包含继承自
UIEvent的属性:
TouchEvent 处理函数
一种用于 触摸事件 的事件处理函数类型。
<div
onTouchStart={e => console.log('onTouchStart')}
onTouchMove={e => console.log('onTouchMove')}
onTouchEnd={e => console.log('onTouchEnd')}
onTouchCancel={e => console.log('onTouchCancel')}
/>参数
-
e:一个 React 事件对象,带有以下额外的TouchEvent属性:它还包含继承自
UIEvent的属性:
TransitionEvent 处理函数
一种用于 CSS 过渡事件的事件处理函数类型。
<div
onTransitionEnd={e => console.log('onTransitionEnd')}
/>参数
e:一个 React 事件对象,带有以下额外的TransitionEvent属性:
UIEvent 处理函数
一种用于通用 UI 事件的事件处理函数类型。
<div
onScroll={e => console.log('onScroll')}
/>参数
e:一个 React 事件对象,带有以下额外的UIEvent属性:
WheelEvent 处理函数
一种用于 onWheel 事件的事件处理函数类型。
<div
onWheel={e => console.log('onWheel')}
/>参数
-
e:一个 React 事件对象,带有以下额外的WheelEvent属性:它还包含继承自
MouseEvent的属性:altKeybuttonbuttonsctrlKeyclientXclientYgetModifierState(key)metaKeymovementXmovementYpageXpageYrelatedTargetscreenXscreenYshiftKey
它还包含继承自
UIEvent的属性:
用法
应用 CSS 样式
在 React 中,你可以使用 className. 指定一个 CSS 类。它的工作方式与 HTML 中的 class 属性类似:
<img className="avatar" />然后你在单独的 CSS 文件中为它编写 CSS 规则:
/* 在你的 CSS 中 */
.avatar {
border-radius: 50%;
}React 并不规定你如何添加 CSS 文件。在最简单的情况下,你需要向 HTML 添加一个 <link> 标签。如果你使用构建工具或框架,请查阅其文档,了解如何将 CSS 文件添加到你的项目中。
有时,样式值依赖于数据。使用 style 属性来动态传入一些样式:
<img
className="avatar"
style={{
width: user.imageSize,
height: user.imageSize
}}
/>在上面的示例中,style={{}} 不是一种特殊语法,而是 style={ } JSX 花括号。 中的一个普通 {} 对象。我们建议只有在样式依赖于 JavaScript 变量时才使用 style 属性。
export default function Avatar({ user }) { return ( <img src={user.imageUrl} alt={'照片:' + user.name} className="avatar" style={{ width: user.imageSize, height: user.imageSize }} /> ); }
Deep Dive
要有条件地应用 CSS 类,你需要自己使用 JavaScript 生成 className 字符串。
例如,className={'row ' + (isSelected ? 'selected': '')} 会根据 isSelected 是否为 true,生成 className="row" 或 className="row selected"。
为了让它更易读,你可以使用一个轻量的辅助库,比如 classnames:
import cn from 'classnames';
function Row({ isSelected }) {
return (
<div className={cn('row', isSelected && 'selected')}>
...
</div>
);
}如果你有多个条件类,这会特别方便:
import cn from 'classnames';
function Row({ isSelected, size }) {
return (
<div className={cn('row', {
selected: isSelected,
large: size === 'large',
small: size === 'small',
})}>
...
</div>
);
}使用 ref 操作 DOM 节点
有时,你需要获取与 JSX 中某个标签关联的浏览器 DOM 节点。例如,如果你想在按钮被点击时聚焦一个 <input>,你需要在浏览器的 <input> DOM 节点上调用 focus()。
要获取某个标签对应的浏览器 DOM 节点,声明一个 ref 并将其作为 ref 属性传给该标签:
import { useRef } from 'react';
export default function Form() {
const inputRef = useRef(null);
// ...
return (
<input ref={inputRef} />
// ...在渲染到屏幕后,React 会把 DOM 节点放入 inputRef.current 中。
import { useRef } from 'react'; export default function Form() { const inputRef = useRef(null); function handleClick() { inputRef.current.focus(); } return ( <> <input ref={inputRef} /> <button onClick={handleClick}> 聚焦输入框 </button> </> ); }
进一步了解 使用 refs 操作 DOM 和 查看更多示例。
对于更高级的用例,ref 属性也接受一个 回调函数。
危险地设置 inner HTML
你可以像这样向元素传递一段原始 HTML 字符串:
const markup = { __html: '<p>一些原始 html</p>' };
return <div dangerouslySetInnerHTML={markup} />;这是危险的。与底层 DOM 的 innerHTML 属性一样,你必须格外小心!除非这段标记来自完全可信的来源,否则很容易通过这种方式引入 XSS 漏洞。
例如,如果你使用一个将 Markdown 转换为 HTML 的 Markdown 库,你信任它的解析器没有 bug,并且用户只会看到自己的输入,那么你可以像这样显示生成的 HTML:
import { Remarkable } from 'remarkable'; const md = new Remarkable(); function renderMarkdownToHTML(markdown) { // 这只有在安全时才成立,因为输出的 HTML // 会展示给同一个用户,而且你 // 信任这个 Markdown 解析器没有 bug。 const renderedHTML = md.render(markdown); return {__html: renderedHTML}; } export default function MarkdownPreview({ markdown }) { const markup = renderMarkdownToHTML(markdown); return <div dangerouslySetInnerHTML={markup} />; }
{__html} 对象应尽可能在生成 HTML 的位置附近创建,就像上面的示例在 renderMarkdownToHTML 函数中所做的那样。这样可以确保代码中使用的所有原始 HTML 都被明确标记,同时也确保只有你期望包含 HTML 的变量会传给 dangerouslySetInnerHTML。不建议像 <div dangerouslySetInnerHTML={{__html: markup}} /> 这样内联创建该对象。
要了解为什么渲染任意 HTML 是危险的,请将上面的代码替换为以下内容:
const post = {
// 想象一下,这段内容存储在数据库中。
content: `<img src="" onerror='alert("you were hacked")'>`
};
export default function MarkdownPreview() {
// 🔴 安全漏洞:将不受信任的输入传递给 dangerouslySetInnerHTML
const markup = { __html: post.content };
return <div dangerouslySetInnerHTML={markup} />;
}嵌入在 HTML 中的代码会运行。黑客可以利用这个安全漏洞窃取用户信息,或者代表他们执行操作。只应将 dangerouslySetInnerHTML 用于可信且经过清理的数据。
处理鼠标事件
此示例展示了一些常见的 鼠标事件 以及它们何时触发。
export default function MouseExample() { return ( <div onMouseEnter={e => console.log('onMouseEnter (parent)')} onMouseLeave={e => console.log('onMouseLeave (parent)')} > <button onClick={e => console.log('onClick (first button)')} onMouseDown={e => console.log('onMouseDown (first button)')} onMouseEnter={e => console.log('onMouseEnter (first button)')} onMouseLeave={e => console.log('onMouseLeave (first button)')} onMouseOver={e => console.log('onMouseOver (first button)')} onMouseUp={e => console.log('onMouseUp (first button)')} > 第一个按钮 </button> <button onClick={e => console.log('onClick (second button)')} onMouseDown={e => console.log('onMouseDown (second button)')} onMouseEnter={e => console.log('onMouseEnter (second button)')} onMouseLeave={e => console.log('onMouseLeave (second button)')} onMouseOver={e => console.log('onMouseOver (second button)')} onMouseUp={e => console.log('onMouseUp (second button)')} > 第二个按钮 </button> </div> ); }
export default function PointerExample() { return ( <div onPointerEnter={e => console.log('onPointerEnter (parent)')} onPointerLeave={e => console.log('onPointerLeave (parent)')} style={{ padding: 20, backgroundColor: '#ddd' }} > <div onPointerDown={e => console.log('onPointerDown (first child)')} onPointerEnter={e => console.log('onPointerEnter (first child)')} onPointerLeave={e => console.log('onPointerLeave (first child)')} onPointerMove={e => console.log('onPointerMove (first child)')} onPointerUp={e => console.log('onPointerUp (first child)')} style={{ padding: 20, backgroundColor: 'lightyellow' }} > 第一个子元素 </div> <div onPointerDown={e => console.log('onPointerDown (second child)')} onPointerEnter={e => console.log('onPointerEnter (second child)')} onPointerLeave={e => console.log('onPointerLeave (second child)')} onPointerMove={e => console.log('onPointerMove (second child)')} onPointerUp={e => console.log('onPointerUp (second child)')} style={{ padding: 20, backgroundColor: 'lightblue' }} > 第二个子元素 </div> </div> ); }
处理焦点事件
在 React 中,焦点事件 会冒泡。你可以使用 currentTarget 和 relatedTarget 来区分聚焦或失焦事件是否源自父元素外部。这个示例展示了如何检测子元素获得焦点、父元素获得焦点,以及如何检测焦点进入或离开整个子树。
export default function FocusExample() { return ( <div tabIndex={1} onFocus={(e) => { if (e.currentTarget === e.target) { console.log('focused parent'); } else { console.log('focused child', e.target.name); } if (!e.currentTarget.contains(e.relatedTarget)) { // 在子元素之间切换焦点时不会触发 console.log('focus entered parent'); } }} onBlur={(e) => { if (e.currentTarget === e.target) { console.log('unfocused parent'); } else { console.log('unfocused child', e.target.name); } if (!e.currentTarget.contains(e.relatedTarget)) { // 在子元素之间切换焦点时不会触发 console.log('focus left parent'); } }} > <label> 名字: <input name="firstName" /> </label> <label> 姓氏: <input name="lastName" /> </label> </div> ); }
export default function KeyboardExample() { return ( <label> 名字: <input name="firstName" onKeyDown={e => console.log('onKeyDown:', e.key, e.code)} onKeyUp={e => console.log('onKeyUp:', e.key, e.code)} /> </label> ); }