What is the right way to use Jquery in React?

I am trying to work on a project which is using a Layout/Template which uses a lot of jQuery.

I have learned to integrate the template with ReactJS Project, however, I am looking for a solution where I can completely replace the jQuery.

One of my solution is to use jQuery functions inside ComponentDidMount() or Render() function of React.

Is this approach correct? Is it the right way?

I have attached a small example below:

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;
           });

    });

}

This is my Render Function.

{/* <!--- 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>

Answers:

Answer

Is this approach correct? Is it the right way?

No. No approach is correct and there is no right way to use both jQuery and React/Angular/Vue together.

The reason is that jQuery manipulates the DOM by, for example, selecting elements and adding/deleting stuff into/from them.

The other frameworks don't manipulate the DOM, they generate it from data, and regenerate it when the data changes.

The problem is, jQuery has no clue about React's presence and actions, and React has no clue about jQuery's presence and actions. This will necessarily lead to a broken application, full of hacks and workarounds, unmaintainable, not to mention that you have to load two libraries instead of one.

Solution : use jQuery OR React, not both together.

Answer

Is this approach correct? Is it the right way?

No. Don't use jQuery to attach event listeners to DOM elements created and managed by React. Use onClick'. I could not find#sidebarCollapse` in your snippet. It could look something like this.

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

And the class for <nav id="sidebar"> could dependent on this state

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

You'll notice, you hand over running operations like adding removing class, attributes and other DOM operations to React and simply declare how things must react to state changes. Amidst this, if you try to run jQuery operations, your UI could probably end up in an inconsistent state.

Migration could be done like this: replace parts of your UI elements with React. For eg, initially you could do,

<!-- 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 -->

And React side could look like this,

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

// MyNavBar.js could have the react components

This way you can incrementally migrate to React and still have jQuery side by side. Just dont manipulate the each other DOM elements.

Sometimes you need a jQuery plugins (animations, visualisations charts etc) inside a React component. Use refs!

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 */}
    );
  }
}

Again, refrain from touching your jQuery's DOM in React and vice versa.

Answer

I've recommend you to use a provider plugin in your webpack.config:

Is really simple to use, and it allows you to use jquery in all your project without importing the package in every file:

More Info Docs: https://webpack.js.org/plugins/provide-plugin/?

So you just have to add this plugin in your webpack.config file:

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

jQuery and react can very well when together only if they don't interact with each other. If you choose to use jQuery use only jQuery to manipulate the dom not both. And way is to use jQuery outside the react Js file in your index.html Please note: this will work only if the page you query loads first

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.