React组件中如何用jQuery的$(this)选中当前点击元素?
问题原因分析
你遇到的核心问题是**this的指向被绑定改变了**:因为你在构造函数里执行了this.setIndex = this.setIndex.bind(this),这会把setIndex函数里的this强制绑定为React组件的实例(也就是JunkListItem对象),而不是你点击的DOM元素。所以当你在setIndex里用$(this)时,其实是把React组件实例包装成了jQuery对象,自然无法选中你点击的那个复选框元素。
解决方案
我提供两种方案,优先推荐第二种(更符合React的设计理念):
方案1:利用React事件对象获取DOM元素(保留jQuery)
React的事件处理函数会自动接收一个event参数,你可以通过event.currentTarget获取到绑定了点击事件的DOM元素(也就是.check-box),然后再用jQuery操作它的子元素:
import React from 'react'; const $ = require('jquery'); export default class JunkListItem extends React.Component { constructor(props ) { super(props); this.state={ selected: false, }; this.setIndex = this.setIndex.bind(this); } setIndex(event) { // 获取绑定点击事件的.check-box元素 const $checkbox = $(event.currentTarget); // 找到里面的div子元素 const $innerDiv = $checkbox.find('div'); // 直接切换类名,不用写if-else,jQuery的toggleClass更简洁 $innerDiv.toggleClass('scale-off'); } render() { return( <li className="item"> <div className="image-box"> <img className="no-select" src={`./images/${this.props.src}.${this.props.type}`} alt={this.props.itemName}/> </div> <div className="details"> <h3>{this.props.itemName}</h3> <p>{this.props.itemDetails}</p> </div> <div className="check-box" onClick={this.setIndex}> <div className='selected' /> </div> </li> ); } }
这里用event.currentTarget而不是event.target的原因是:currentTarget始终指向绑定了事件的元素(也就是.check-box),而target可能指向它的子元素(比如你点击到里面的div.selected时),用currentTarget更稳定。
方案2:用React状态管理(完全抛弃jQuery,推荐)
React的设计理念是用状态控制DOM渲染,而不是直接操作DOM。你可以给每个组件维护一个selected状态,然后在render的时候根据状态动态添加类名,这样既避免了jQuery操作DOM的冲突,也更符合React的模式:
import React from 'react'; export default class JunkListItem extends React.Component { constructor(props ) { super(props); this.state={ selected: false, }; this.setIndex = this.setIndex.bind(this); } setIndex() { // 切换selected状态,用prevState确保状态更新的正确性 this.setState(prevState => ({ selected: !prevState.selected })); } render() { // 根据状态动态生成类名 const innerDivClass = this.state.selected ? 'selected' : 'selected scale-off'; return( <li className="item"> <div className="image-box"> <img className="no-select" src={`./images/${this.props.src}.${this.props.type}`} alt={this.props.itemName}/> </div> <div className="details"> <h3>{this.props.itemName}</h3> <p>{this.props.itemDetails}</p> </div> <div className="check-box" onClick={this.setIndex}> <div className={innerDivClass} /> </div> </li> ); } }
这种方式的好处是:
- 完全遵循React的单向数据流,状态变化自动触发DOM更新
- 避免了React虚拟DOM和jQuery直接操作DOM可能产生的不一致问题
- 代码更简洁,逻辑更清晰
内容的提问来源于stack exchange,提问作者MHF
相关产品推荐
相关产品推荐

