I'm new to ReactJS. Previously I've used jQuery to set any animation or feature that I needed. But now I'm trying to use ReactJS and minimize the use of jQuery.
My Case is:
I'm trying to build an accordion with ReactJS.
<div class="accor">
<div class="head">Head 1</div>
<div class="body hide">Body 1</div>
</div>
<div class="accor">
<div class="head">Head 1</div>
<div class="body hide">Body 1</div>
</div>
<div class="accor">
<div class="head">Head 1</div>
<div class="body hide">Body 1</div>
</div>
using JQuery:
$('.accor > .head').on('click', function(){
$('.accor > .body').slideUp();
$(this).next().slideDown();
});
My Question:
How can I do this with ReactJS?
Yes, we can use jQuery in ReactJs. Here I will tell how we can use it using npm.
step 1: Go to your project folder where the package.json file is present via using terminal using cd command.
step 2: Write the following command to install jquery using npm :
npm install jquery --save
npm i --save-dev #types/jquery
step 3: Now, import $ from jquery into your jsx file where you need to use.
Example:
write the below in index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
// react code here
$("button").click(function(){
$.get("demo_test.asp", function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
// react code here
write the below in index.html
<!DOCTYPE html>
<html>
<head>
<script src="index.jsx"></script>
<!-- other scripting files -->
</head>
<body>
<!-- other useful tags -->
<div id="div1">
<h2>Let jQuery AJAX Change This Text</h2>
</div>
<button>Get External Content</button>
</body>
</html>
You should try and avoid jQuery in ReactJS. But if you really want to use it, you'd put it in componentDidMount() lifecycle function of the component.
e.g.
class App extends React.Component {
componentDidMount() {
// Jquery here $(...)...
}
// ...
}
Ideally, you'd want to create a reusable Accordion component. For this you could use Jquery, or just use plain javascript + CSS.
class Accordion extends React.Component {
constructor() {
super();
this._handleClick = this._handleClick.bind(this);
}
componentDidMount() {
this._handleClick();
}
_handleClick() {
const acc = this._acc.children;
for (let i = 0; i < acc.length; i++) {
let a = acc[i];
a.onclick = () => a.classList.toggle("active");
}
}
render() {
return (
<div
ref={a => this._acc = a}
onClick={this._handleClick}>
{this.props.children}
</div>
)
}
}
Then you can use it in any component like so:
class App extends React.Component {
render() {
return (
<div>
<Accordion>
<div className="accor">
<div className="head">Head 1</div>
<div className="body"></div>
</div>
</Accordion>
</div>
);
}
}
Codepen link here: https://codepen.io/jzmmm/pen/JKLwEA?editors=0110
Step 1:
npm install jquery
Step 2:
touch loader.js
Somewhere in your project folder
Step 3:
//loader.js
window.$ = window.jQuery = require('jquery')
Step 4:
Import the loader into your root file before you import the files which require jQuery
//App.js
import '<pathToYourLoader>/loader.js'
Step 5:
Now use jQuery anywhere in your code:
//SomeReact.js
class SomeClass extends React.Compontent {
...
handleClick = () => {
$('.accor > .head').on('click', function(){
$('.accor > .body').slideUp();
$(this).next().slideDown();
});
}
...
export default SomeClass
Earlier,I was facing problem in using jquery with React js,so I did following steps to make it working-
npm install jquery --save
Then, import $ from "jquery";
See here
To install it, just run the command
npm install jquery
or
yarn add jquery
then you can import it in your file like
import $ from 'jquery';
I read a lot about jQuery and ReactJS; they have been always advised to avoid using jQuery in ReactJS apps.
If you want to create an accordion, you can do it with React-Bootstrap:
React-Bootstrap Accordion Component
I was tried bellow script and its work fine for me.
Install jQuery : npm install jquery
Import $ from jQuery : import $ from "jquery";
Write bellow code on Component Did Mount Method
componentDidMount() {
$(document).on('click','.accor > .head',function(){
`var closestDiv = $(this).closest('.accor');`
`closestDiv.find('.body').slideToggle();`
});
}
You can use JQuery with React without doing:
import $ from 'jquery'
To do so, you need to go to the root folder where package.json in your terminal and type this command:
yarn add -D expose-loader
Then add this configuration to your webpack.config.js file:
module: {
rules: [
{test: require.resolve('jquery'), loader: 'expose-loader?$!expose-loader?jQuery'}
]
}
This exposes $ and jQuery to the global scope, so you can use them anywhere in your code.
Don't forget to add Jquery to your vendor bundle like this:
module.exports = config({
entry: {
vendor: [
'jquery'
]
}
...
Now you can use jquery without importing it inside your code because that's what expose-loader does for you.
And to test that it works just fine, add this to any file in your project:
console.log($);
and see in your browser console that it will show you the $ variable without throwing an error.
use a style library like bootstrap or MUI to accomplish this. react has react strap, a solid bootstrap/react component package. the style frameworks can both be used but it is not a good practice to mix them. I would recommend using react strap as i believe it has better react components, personal preference.
if you continue in react, you will find that jquery is not the best solution. it may work but since react and jquery are bothing working from the dom (and react manages a shadow dom) you might have issues. someone had mentioned using the react lifecycles to use the library on mount or load. for those of us using the newer functional components & hooks (react 16+ i believe) we can use the useEffect hook to call it on load.
useEffect(() => {
// use jquery here if you must, this way the component is loaded
//and the dom matches whats in react (or should)
}, []);
the style and component libraries are best practice. for the same reason you would use formik to manage a form component (to not have to re-create the wheel/form every time) the same is true for the style component libraries.
https://www.npmjs.com/package/reactstrap
https://getbootstrap.com/docs/5.0/components/accordion/
https://mui.com/components/accordion/
Best is not to mix React and jQuery if you require it for any jQuery plugins. It will not work as event handlers (like onclick) in jQuery do no work.
See excellent answer here:
What is the right way to use Jquery in React?
If you really have to mix the two, read here:
https://reactjs.org/docs/integrating-with-other-libraries.html
$('.simpleCart_input').blur(function() {
var val = $.trim(this.value);
$(this).wrap($('<span/>', {
'class': $(this).attr('class'),
html: val
})).remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="simpleCart_input" style="background-color:yellow; color:balck; border-radius:6px; height:90px; width:100px;" />
React jquery plugin is a node package that will help you using jQuery plugins easily with ReactJs.
npm i react-jquery-plugin
or
yarn add react-jquery-plugin
USAGE:
import React, { useEffect } from 'react'
import { $ } from 'react-jquery-plugin'
export default function App() {
//if you're using LifeCycle methods
// componentDidMount() {
// $(window).scroll(() => {
// // put your code here
// });
// }
// With lifeCycle Hooks
useEffect(() => {
$(window).scroll(() => {
// put your code here
});
}, [])
return (
<div>
<h1>Hello React with jQuery</h1>
</div>
)
}
If you need to add jQuery code for all your React App then you should add the jQuery in componentDidMount() lifecycle function of the component:
class App extends React.Component {
componentDidMount() {
// Jquery Code for All components of the React App
}
}
But, if you need to use jQuery code in each component in the App, you should put your code in the useEffect()
const ComponentExample = () => {
useEffect(() => {
// Jquery Code for this component
})
return (
<div>
<h1></h1>
</div>
)
}
Related
I have added Intro.js as below in one of my components:
import introJs from 'intro.js';
Then called it in componentDidMount
componentDidMount() {
introJs().start();
}
Element where I am using it at:
<div className={cx('dropDownSortingBlock')}>
{!isTrending && <div className={cx('dropDown')} data-intro={'Hello step one!'}>
However when i import css into a parent component
It doesn't render the component.
Update:
I tried using intro.js react wrapper and i have imported css directly into my file now.
However it just doesn't work
constructor() {
super();
this.state = {
showMessage: false,
type: '',
message: '',
stepsEnabled: true,
initialStep: 0,
steps: [
{
element: '.snapshotWrapper',
intro: 'Hello step',
},
{
element: '.snapshotWrapperNew',
intro: 'Hello Sort wrapper',
},
],
};
}
In render
<Steps
enabled={this.state.stepsEnabled}
steps={this.state.steps}
initialStep={this.state.initialStep}
onExit={this.onExit}
/>
Below is what shows up:
Because you're importing the css file from the package in node_modules , Add the ~ to your import in ListLandingPage.css :
#import "~intro.js/introjs.css";
see Import CSS from "node_modules" in Webpack
Or, import it in your component ( without the ~ ) :
import introJs from 'intro.js';
import 'intro.js/introjs.css';
Howerver, I would suggest you use the React wrapper around Intro.js for a React app.
they even have a code sandbox to get started
Please use react wrapper for intro.js.
npm install intro.js-react
also install intro js -- > npm install intro.js --save
then you can import css files from node modules like this below
import "intro.js/introjs.css"
themes are also available on the themes folder.(for eg: import "intro.js/themes/introjs-
nassim.css";)
Wrapper works similarly. Define steps / hints inside component. for that :-
import { Steps, Hints } from "intro.js-react";
Did you try https://www.npmjs.com/package/intro.js-react . It is a small React wrapper around Intro.js. The wrapper provides support for both steps and hints
I want to use the jQuery Plugin chosen in my vue.js/Webpack with TypeScript application.
I read that it it's best to wrap the plugin in a custom Vue component.
I installed the NPM packages:
npm install jquery --save
npm install #types/jquery --save
npm install chosen-js --save
npm install #types/chosen-js --save
My component:
<template>
<select>
<option value="1">Test1</option>
<option value="2">Test2</option>
</select>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import $ from 'jquery';
import 'chosen-js';
#Component
export default class ChosenSelect extends Vue{
#Prop()options!:string;
#Prop()value!:string;
mounted() {
let vm = this;
let el = $(vm.$el);
console.log(el);
}
}
</script>
Without import 'chosen-js' jQuery is working - when I'm using the component in another component I get a console output.
With import 'chosen-js' I only get Uncaught ReferenceError: jQuery is not defined from the chosen library.
What is the right way to import both - jQuery and chosen-js and use it in a vue Typescript component.
I figured it out thanks to https://medium.com/#NetanelBasal/typescript-integrate-jquery-plugin-in-your-project-e28c6887d8dc
first, install jquery
npm install jquery --save
npm install #types/jquery --save
then in any of your component add this.
import * as $ from 'jquery';
check if jquery works by doing something like this
import * as $ from 'jquery';
export default class Home extends Vue {
created () {
this.test()
}
test () {
console.log($('body')) // It's work
}
}
Sometimes you need to wait for the dom to be loaded in order to do your jquery things.
<template>
<div class="home">
<div id="test">wijfwoe</div>
</div>
</template>
<script>
import * as $ from 'jquery';
export default class Home extends Vue {
created () {
}
mounted () {
let a = $('#test')[0];
console.log(a.textContent);
}
</script>
Put this in the main.ts file and it will be available inside the components.
declare global {
interface Window { $: any; }
}
window.$ = require('jquery')
I would suggest using a Vue-specific select plugin, rather than having to rely on a jQuery-based one that somewhat defeats the purpose of using something like Vue in terms of DOM manipulations. Most of these already bring in their own components, so there's no need to create a wrapper.
There's a great list of Vue resources maintained here, not just for plugins: awesome-vue
Even after googling, I'm having trouble finding the best way to import/include jQuery, Masonry and some other jQuery based libraries in my GatsbyJS project using the webpack pipeline.
I can include tags manually, but my understanding is that it's ideal to use import so it gets pipelined and packed.
import jQuery from '../js/jquery.min.js'
import '../js/flickr.js'
import '../js/flexslider.min.js'
import '../js/lightbox.min.js'
import '../js/masonry.min.js'
This always produces the error:
ReferenceError: jQuery is not defined
from the flickr.js & masonry..min.js libraries
You should have a look on the excellent ReactJS doc on How to integrate React with other libraries.
The idea is to attach a ref to an empty <div /> and reference to it in componentDidMount()where you can pass it to your jQuery plugin.
code from the react's doc:
class SomePlugin extends React.Component {
componentDidMount() {
this.$el = $(this.el);
this.$el.somePlugin();
}
componentWillUnmount() {
this.$el.somePlugin('destroy');
}
render() {
return <div ref={el => this.el = el} />;
}
}
I have a React Redux application. Im adding materialize as the CSS framework, but materialize requires jquery. So i installed Jquery and added it to my project via npm. If i import jquery like so
import $ from 'jquery';
No errors are thrown and im able to use it. But only on that component. So i added the wepback plug so i can call $ anymore in my react application. However, when i do this as described on webpacks website, it get the following error.
Line 13: '$' is not defined
Any ideas on why this is ?
app.js
import React from 'react';
import '../styles/index.css';
import Header from './header/Header';
class App extends React.Component {
constructor(props){
super(props);
console.log('Application ready');
}
componentWillMount(){
$('ul.tabs').tabs();
}
render = () => (
<div>
<Header />
<div>
{this.props.children}
</div>
</div>
)
}
export default App;
webpack.config.dev.js
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
jquery: "jquery/src/jquery" // What i added
// $: "jquery/src/jquery"
},
jquery is in the node_modules folder, from the npm install, i didnt add it to any other location.
You've aliased jQuery to the global variable jQuery, not $ - do alias: { $: 'jquery' }.
Wrong, this isn't what alias is for, see https://webpack.js.org/configuration/resolve/
Global variables in (browser) JS are really properties of window. So at the start of your script you could do
import $ from 'jquery';
window.$ = $;
and it'd be available globally after that. Including jQuery in its own <script> tag would do the same thing. But these are both un-webpack, a bit naughty, not modular. The 'correct' thing to do is import $ from 'jquery' in every file where you need it. Yeah this will be tedious if you need it in a lot of places, but it means you know where you need jQuery and where you don't, and if you removed all the components that used jQuery, jQuery would disappear as well.
To add on for Gatsby.js you can npm i jquery and then import jquery in gatsby-browser.js.
import 'jquery/dist/jquery.min';
import 'popper.js/dist/popper.min'; // for navbar animation
import 'bootstrap/dist/js/bootstrap.min';
import $ from 'jquery'; in the relevant files will then detect $
I’m trying to use clipboard.js in a React component, and it causes my devserver to start failing with the Node error:
ReferenceError: Element is not defined
at Object.<anonymous> (/mnt/home/me/code/board/webapp/node_modules/matches-selector/index.js:6:13)
I initialize the clipboard in componentDidMount but am still getting this error. I actually think the error may have something to do with my import, because even when I don’t actually initialize the clipboard (but include the import) I get the error. Does anyone have an idea what I might be doing wrong?
Relevant code (styling excluded):
import React, { Component } from 'react';
import Clipboard from 'clipboard';
export default class CodeSnippet extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
new Clipboard('.copyButton', {
target: () => document.getElementById('snippet')
});
}
render() {
return (
<div style={styles.snippetCopy}>
<div id="snippet" style={styles.snippet}>
{'this text will copy'}
</div>
<button
className={"copyButton"}
id="clipper"
data-clipboard-text='snippet'
style={styles.buttonStyle}
text={'Copy code'}>
</button>
</div>
);
}
}
You can't require clipboard.js if you're doing server side rendering. It's annoying but instead of installing via npm, they suggest including the script manually like this:
<script src="https://cdn.jsdelivr.net/clipboard.js/1.5.12/clipboard.min.js"></script>
https://github.com/zenorocha/clipboard.js/issues/157
I created a fiddle updating your code. It's a suggestion of integrating clipboardjs and React, using ref's and clipboardjs' text function.
Check here: https://jsfiddle.net/mrlew/L54ky6hj/