簡體   English   中英

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

[英]What is the right way to use Jquery in React?

我正在嘗試處理一個使用大量 jQuery 的布局/模板的項目。

我已經學會了將模板與 ReactJS 項目集成,但是,我正在尋找一種可以完全替換 jQuery 的解決方案。

我的解決方案之一是在 React 的ComponentDidMount()Render()函數中使用 jQuery 函數。

這種方法是否正確? 這是正確的方法嗎?

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

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>

這種方法是否正確? 這是正確的方法嗎?

不。沒有任何方法是正確的,也沒有正確的方法來同時使用 jQuery 和 React/Angular/Vue。

jQuery 通過例如選擇元素並向其中添加/刪除內容來操作 DOM。 通常,它選擇一個現有的<div>並設置其文本。

其他框架不操作 DOM; 他們從數據生成它,並在數據發生變化時重新生成它(例如在 Ajax 調用之后)。

問題是,jQuery 不知道 React 的存在和動作,而 React 也不知道 jQuery 的存在和動作。

這必然會導致應用程序損壞,充滿黑客和變通方法,無法維護,更不用說您必須加載兩個庫而不是一個。

例如,jQuery 將選擇一個<button>並將其添加到.click()偵聽器; 但是一秒鍾之后,React/Angular/Vue 可能會在此過程中重新生成 DOM 和按鈕,從而使 jQuery 的.click()無效。 所以你會在 Stackoverflow 上問一個問題,想知道為什么你的.click()不起作用。 你最終會添加一個骯臟的setTimeout() hack,以便延遲 jQuery 的click()處理程序附件,直到 React 重新生成你的按鈕之后。 這是你通往地獄的高速公路。

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

這種方法是否正確? 這是正確的方法嗎?

不。不要使用 jQuery 將事件偵聽器附加到由 React 創建和管理的 DOM 元素。 使用onClick'. I could not find onClick'. I could not find在您的代碼段中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,並簡單地聲明事物必須如何對狀態更改做出反應。 在此期間,如果您嘗試運行 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 請注意:這僅在您查詢的頁面首先加載時才有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM