在 React 中使用 Jquery 的正确方法是什么?

IT技术 javascript jquery reactjs
2021-02-08 03:40:02

我正在尝试处理一个使用大量 jQuery 的布局/模板的项目。

我已经学会了将模板与 ReactJS 项目集成,但是,我正在寻找一种可以完全替换 jQuery 的解决方案。

我的解决方案之一是在React内部使用 jQuery 函数ComponentDidMount()Render()函数。

这种方法是否正确?这是正确的方法吗?

我在下面附上了一个小例子:

import React, { Component } from 'react';
import '../stylesheets/commonstyles.css';
import '../stylesheets/bootstrap-sidebar.css';
import '../stylesheets/sidebar1.css';
import $ from 'jquery';
 class NavBar extends Component {
   constructor(props){

      super(props);
      this.openSidebar = this.openSidebar.bind(this);

   }

  openSidebar(){

      console.log('hello sidebar');

  }
  componentWillMount(){

    $(document).ready(function () {
        $('#sidebarCollapse').on('click', function () {
            $('#sidebar').toggleClass('active');
        });
        $('.search-btn').on("click", function () {
          $('.search').toggleClass("search-open");
            return false;
           });

    });

}

这是我的Render功能。

{/* <!--- SIDEBAR -------> */}
 <div class="wrapper" style={{paddingTop:60}}>
           {/* <!-- Sidebar Holder --> */ }
            <nav id="sidebar">
                <div class="sidebar-header">
                    <h3>Dashboard</h3>
                    <strong>BS</strong>
                </div>

                <ul class="list-unstyled components">
                    <li class="active">
                        <a href="#homeSubmenu" /*data-toggle="collapse" */ aria-expanded="false">
                            <i class="ti-home"></i>
                            Home
                        </a>
                        <ul class="collapse list-unstyled" id="homeSubmenu">
                            <li><a href="#">Home 1</a></li>
                            <li><a href="#">Home 2</a></li>
                            <li><a href="#">Home 3</a></li>
                        </ul>
                    </li>
                    <li>
                        <a href="#" style={{color:"white"}}>
                            <i class="ti-align-justify" ></i>
                            About
                        </a>
                        <a href="#pageSubmenu" /*data-toggle="collapse" */ aria-expanded="false" style={{color:"white"}}>
                            <i class="ti-text"></i>
                            Pages
                        </a>
                        <ul class="collapse list-unstyled" id="pageSubmenu">
                            <li><a href="#">Page 1</a></li>
                            <li><a href="#">Page 2</a></li>
                            <li><a href="#">Page 3</a></li>
                        </ul>
                    </li>
                    <li>
                        <a href="#" style={{color:"white"}}>
                            <i class="ti-paragraph"></i>
                            Portfolio
                        </a>
                    </li>
                    <li>
                        <a href="#" style={{color:"white"}}>
                            <i class="ti-control-play"></i>
                            FAQ
                        </a>
                    </li>
                    <li>
                        <a href="#" style={{color:"white"}}>
                            <i class="ti-share-alt"></i>
                            Contact
                        </a>
                    </li>
                </ul>
            </nav>

            { /* <!-- Page Content Holder --> */ }
            <div id="content">  


            </div>
        </div>
4个回答

这种方法是否正确?这是正确的方法吗?

不。没有任何方法是正确的,也没有将 jQuery 和 React/Angular/Vue 一起使用的正确方法。

jQuery 通过例如选择元素并向其中添加/删除内容来操作 DOM。通常,它选择一个现有的<div>并设置其文本。

其他框架不操作 DOM;他们从数据生成它,并在数据发生变化时重新生成它(例如在 Ajax 调用之后)。

问题是,jQuery 不知道 React 的存在和动作,而 React 也不知道 jQuery 的存在和动作。

这必然会导致应用程序损坏,充满黑客和变通方法,无法维护,更不用说您必须加载两个库而不是一个。

例如,jQuery 将选择 a<button>并将其添加为.click()侦听器;但是一秒钟之后,React/Angular/Vue 可能会在此过程中重新生成 DOM 和按钮,从而使 jQuery 的.click(). 所以你会在 Stackoverflow 上问一个问题,想知道为什么你.click()不工作。你最终会添加一个肮脏的setTimeout()hack,以延迟 jQuery 的click()处理程序附件,直到 React 重新生成你的按钮之后。这是你通往地狱的高速公路。

解决方案:使用 jQuery OR (React/Angular/Vue),不要同时使用。

你说“jQuery 操作 DOM”。不,你可以告诉 jQuery 去做。您可以通过多种方式使用 jQuery。Se,答案不应该是“不”。这取决于。如果开发人员知道它在做什么,那么可以有一种方法可以同时使用两者。
2021-03-13 03:40:02
谢谢。我当时想知道。那怎么替换jquery提供的动画、饼图等东西呢?你可以很容易地替换jquery的元素切换功能,但是动画和其他东西,如果使用Vanilla JS或其他框架,在模板中转换那些jquery函数,并用react进行优化。
2021-03-16 03:40:02
React 文档概述了如何正确混合库:reactjs.org/docs/integrating-with-other-libraries.html
2021-03-22 03:40:02
虽然您对 jQuery 和 React 搞乱彼此状态的可能性是正确的,但我认为说这两者不能完全一起使用是不对的。一个应用程序可以同时拥有两者,前提是它们没有错误地混合。请更新您的答案,杰里米。将 React 逐步添加到您的堆栈中并没有错。
2021-04-08 03:40:02

这种方法是否正确?这是正确的方法吗?

不。不要使用 jQuery 将事件侦听器附加到由 React 创建和管理的 DOM 元素。onClick'. I could not find在您的代码段中使用#sidebarCollapse`。它可能看起来像这样。

<button id="sidebarCollapse" onClick={state => this.setState({ collapsed: !state.collapsed })>Collapse</button

并且类<nav id="sidebar">可能依赖于这个状态

<nav id="sidebar" className={ this.state.collapsed ? "": "active" } >

您会注意到,您将正在运行的操作(例如添加删除类、属性和其他 DOM 操作)移交给 React,并简单地声明事物必须如何对状态更改做出react。在此期间,如果您尝试运行 jQuery 操作,您的 UI 可能最终会处于不一致的状态。

迁移可以这样完成:用 React 替换部分 UI 元素。例如,最初你可以这样做,

<!-- rest of your existing jQuery based code -->
<header id="reactManagedNavbar">
  <!-- Nothing here. React will take care of DOM Elements here -->
</header>
<!-- rest of your existing jQuery based code -->

而 React 方面可能看起来像这样,

// main.js
ReactDOM.render(<MyNavBar />, document.getElementById('reactManagedNavBar'))

// MyNavBar.js could have the react components

通过这种方式,您可以逐步迁移到 React,并且仍然可以并排使用 jQuery。只是不要操作彼此的 DOM 元素。

有时您需要在 React 组件中使用 jQuery 插件(动画、可视化图表等)。使用参考!

class MyJQueryDependingComp extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  componentDidMount() {
    // this.myRef.current is the dom element. Pass it to jQuery
  }
  render() {
    return (
       {/* rest of React elements */}
       <div ref={this.myRef} />
       {/* rest of React elements */}
    );
  }
}

同样,不要在 React 中接触 jQuery 的 DOM,反之亦然。

我建议您在 webpack.config 中使用提供程序插件:

使用起来非常简单,它允许您在所有项目中使用 jquery,而无需在每个文件中导入包:

更多信息文档:https : //webpack.js.org/plugins/provide-plugin/

所以你只需要在你的 webpack.config 文件中添加这个插件:

new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery'
});

只有当 jQuery 和 react 不相互交互时,它们才能很好地结合在一起。如果您选择使用 jQuery,请仅使用 jQuery 来操作 dom,而不是同时使用两者。方法是在 index.html 中的 react Js 文件之外使用 jQuery 请注意:这仅在您查询的页面首先加载时才有效

这个答案可能需要一些说明,也许还有一个小代码示例。
2021-03-20 03:40:02