2017-10-20 75 views
4

我知道混合jQuery和ReactJS是不可取的,因为ReactJS没有意识到由jQuery所做的任何DOM修改。但是,如果只使用jQuery来查询DOM并轻松方便地查找节点,同时将所有DOM编辑留给ReactJS。除了jQuery是一个大型图书馆之外,还有其他的缺点吗?React的jQuery选择器可以吗?

一个示例用例设置事件侦听器,只要下拉菜单组件安装时检查用户是否在菜单的任何地方点击,以便菜单可以关闭。 jQuery .parents()方法是检查点击目标是否是菜单容器元素的子项的非常方便的方法。在ReactJSvanilla JavaScript有没有简单的方法来做到这一点?

下面是这个例子的代码示例:

handleClick = e => { 
    const element = $(e.target) 
    if(!(element.parents('.menu').length || element.hasClass('menu'))) { 
    this.setState({ menuOpen: false }) 
    } 
} 

componentWillUpdate (nextProps, nextState) { 
    if(nextState.menuOpen && !this.state.menuOpen) { 
    document.addEventListener('click', this.handleClick, false) 
    } else if (!nextState.menuOpen && this.state.menuOpen) { 
    document.removeEventListener('click', this.handleClick, false) 
    } 
} 
+1

如果你只想要jQuery的选择器引擎,请使用[Sizzle](https://sizzlejs.com/)或[Zepto](http://zeptojs.com/)来查看。如果您不担心向后兼容较旧的非常规浏览器,请尝试此解决方案(https://stackoverflow.com/questions/12980877/parents-without-jquery-or-queryselectorall-for-parents)。 – Terry

+0

结帐https://sizzlejs.com/ –

回答

-1

我是在说你的问题纠正归结为:这是OK查询浏览器的DOM为将要使用的信息作出反应? 由于虚拟DOM总是与浏览器DOM同步,因此在浏览器DOM中执行只读查找肯定不会坏。事实上,如果您想添加交互性或用户事件处理,您有时需要在浏览器DOM上执行此操作,而不是虚拟DOM。

然后至于要使用哪个库:除了jQuery,还有更轻的选项,如minifiedjs。

+0

是的,这是正确的,我正在检查是否有任何缺陷使用类似jQuery的库进行浏览器DOM查找。你的建议是没有任何主要的,如果有的话,所以没关系。我会等着看有没有人能拿出任何其他的东西,否则我会把你的标记作为答案。谢谢! –

+0

这里需要注意的一点是,React已经有一个[API访问](https://reactjs.org/docs/react-dom.html)DOM,您应该比较喜欢jQuery。 –

1

是的,我会说在React中使用jQuery有缺点。

的VDOM版本比较算法会感到困惑

这是一个你提到的。是的,如果您只使用read-only属性,那么效果会很好,但除非您将目标锁定为旧版浏览器,否则document.querySelector之类的内容重量更轻。

你要引入的每一个依赖,特别是像图书馆那样大的一个,应该仔细审查。详情请参阅the website obesity epedemic。我们将在下一个例子中看到,“我只会用它来阅读并让React去做其余的事情”的想法会给你的代码增加一个很大的混淆层,如下所示。

你放弃的方式做出反应

在我看来,更大的问题是放弃作出反应的方式。用一句话来描述React,我会说:

React是一个基于组件的库,用于生成从state输入派生的HTML,CSS和JavaScript功能。

比方说,我有一个简单的UserProfile组件。此组件将有一些数据关于用户,包括一个开关以接收推送通知或不:

// Please note this is simplified pseudo-code, and will likely not work 
class UserProfile extends Component { 
    state = { 
    name: 'Bob', 
    profilePic: 'someurl.com/profile-pic', 
    isReceivingNotifications: false 
    } 

    updateReceivingNotifications =() => { 
    this.setState({ isReceivingNotifications: !this.state.isReceivingNotifications }) 
    } 

    render() { 
    const { name, profilePic, isReceivingNotifcations } = this.state; 
    return (
     <div> 
     <h2>{name}</h2> 
     <img src={profilePic} /> 
     <input type="checkbox" checked={isReceivingNotifications} onChange={this.updateReceivingNotifications} /> 
     </div> 
    ); 
    } 
} 

简单,部件呈现从组件的状态的。如果isReceivingNotifcations为true,则复选框将被选中。

让我们看看所提出的设计模式,这同例如:

class UserProfile extends Component { 
    state = { 
    name: 'Bob', 
    profilePic: 'someurl.com/profile-pic', 
    isReceivingNotifications: false 
    } 

    componentDidMount() { 
    const checkBox = document.getElementById('my-checkbox'); 
    const that = this; 
    // Use a regular function to bind the this context to the checkbox instead of component 
    checkBox.addEventListener('change', function() { 
     if (this.checked) { 
     that.setState({ isReceivingNotifcations: true }); 
     } else { 
     that.setState({ isReceivingNotifcations: false }); 
     } 
    }); 
    } 

    render() { 
    const { name, profilePic, isReceivingNotifcations } = this.state; 
    return (
     <div> 
     <h2>{name}</h2> 
     <img src={profilePic} /> 
     <input 
      type="checkbox" 
      checked={isReceivingNotifications} 
      id="my-checkbox" 
      /> 
     </div> 
    ); 
    } 
} 

首先是干净多了,无论你如何使用jQuery或任何DOM操作库,你会使用这个格式。

这是一个人为的例子,但每次我在现实生活中看到这个版本的时候,都是一团糟。

最后,为什么?

只需要一点时间并学习React设计模式。我建议。 jQuery应该是最后的手段,因为你使用React是出于我假设的原因。

有一个例外,这是jQuery的库您使用阵营

在这种情况下,你有超过重写库中的其他没有其他选择。如this article中突出显示的那样,您应该编写一个包装组件来使其符合React。

+0

当然,对于所有用户交互都包含在该组件中的组件,DOM查询是不必要的。但是如果你需要一个组件来发现在它之外发生的点击呢?您可以找到HOC,检查点击是否发生在外部,但他们可能在内部使用DOM查询。也许不是JQuery,而是一个DOM查询。而且更重要的是,如果要求更加复杂呢?如果我需要知道点击是否发生在当前某个特定组件之外?反应的实现将非常复杂 –

+0

我会说这是使用较不常见的场景来证明一个更常见的场景。不常见的情况是组件外的组件操作(模块,菜单等)。现在,我们有[门户](https://reactjs.org/docs/portals.html)来处理这种确切的情况。 –

相关问题