React应用中onFocus与onBlur事件不生效问题排查与解决
故障原因
- 事件处理函数作用域错误:
FocusInput、BlurInput被定义在render方法内的Dimmer函数局部作用域中,JSX模板绑定事件时无法访问到这两个函数,绑定值实际为undefined,自然不会触发。 - 无效冗余代码:定义的
Dimmer函数从未被调用,内部逻辑完全不会执行。 - 缺失核心DOM节点:代码中没有渲染类名为
searchDimmer的遮罩层元素,就算事件正常触发,jQuery也找不到目标节点执行动画。 - 实现方式不符合React设计逻辑:类组件中直接引入jQuery操作命令式修改DOM,容易出现状态和DOM不同步的问题。
修复方案
推荐实现(无jQuery,符合React开发规范)
用组件自身状态控制遮罩显隐,CSS实现淡入淡出过渡,性能更好也更易维护。
组件代码:
import React from 'react'; import './SearchBox.scss'; import {IoSearchOutline} from 'react-icons/io5' class SearchBox extends React.Component { state = { dimmerVisible: false } handleInputFocus = () => { this.setState({ dimmerVisible: true }) } handleInputBlur = () => { this.setState({ dimmerVisible: false }) } render() { return ( <div className="SearchBox"> {/* 遮罩层节点 */} <div className={`searchDimmer ${this.state.dimmerVisible ? 'show' : ''}`}></div> <input onFocus={this.handleInputFocus} onBlur={this.handleInputBlur} type="text" className='SearchBoxInput' id="SearchBoxInput" /> <button className='SearchBoxSubmitButton ButtonCore button' type='submit' > <IoSearchOutline /> </button> </div> ) } }; export default SearchBox;
在SearchBox.scss中补充遮罩样式和过渡动画:
.searchDimmer { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 99; opacity: 0; pointer-events: none; // 200ms淡入淡出过渡和原jQuery动画时长一致 transition: opacity 200ms ease; } .searchDimmer.show { opacity: 1; pointer-events: auto; }
兼容原有jQuery写法的最小修复
如果暂时不想重构逻辑,只解决事件不触发的问题,只需调整作用域、补全遮罩节点即可:
import React from 'react'; import './SearchBox.scss'; import {IoSearchOutline} from 'react-icons/io5' import $ from "jquery"; class SearchBox extends React.Component { // 把事件处理函数定义为类方法,render内可直接访问 handleFocus = () => { $(".searchDimmer").fadeIn(200); } handleBlur = () => { $(".searchDimmer").fadeOut(200); } render() { return ( <div className="SearchBox"> {/* 初始隐藏遮罩层节点 */} <div className="searchDimmer" style={{display: 'none'}}></div> <input onFocus={this.handleFocus} onBlur={this.handleBlur} type="text" className='SearchBoxInput' id="SearchBoxInput" /> <button className='SearchBoxSubmitButton ButtonCore button' type='submit' > <IoSearchOutline /> </button> </div> ) } }; export default SearchBox;
内容的提问来源于stack exchange,提问作者zmih
相关产品推荐
相关产品推荐

