React - '$' is not defined - javascript

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 $

Related

Css not working for intro.js module in React

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

Vue/Webpack/Typescript - How to use jQuery Plugin

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

how use npm packages with Vue SPA

i have created Vuejs app using vue-loader,now i need to use an installed npm package as follow :
var x = require('package-name')
Vue.use(x)
but i have this error :
Uncaught TypeError: plugin.apply is not a function
dose Vuejs require a special type packages or it can work with any JavaScript package and this error can be solved
There are many approaches.
I am adding with respect #smiller comment and thanks for sharing the link . I am adding information here in case the link someday not work .
Credit to this link :- https://vuejsdevelopers.com/2017/04/22/vue-js-libraries-plugins/
First approach of-course #crig_h
window.x = require('package-name')
There are certain drawback . don’t work with server rendering . Otherwise everything will work fine in browser as window is global to browser , any properties attract to it will be accessible to whole app.
The second approach is .
Use Import with the js portion in the .vue file , Like this.
if inside the '.vue' file.
<script>
import _ from 'lodash';
export default {
created() {
console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
}
}
</script>
If you have seperate file for .js then same like this there will we no <script> tag.
And Third method
where ever in the project you import vue. You can write this statement
import Vue from "vue";
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
This will set the relevant properties to to Vue . And you can use it any where like this . As Vue is global scope of app.
export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
ADDED FOR CSS
you can do import in src/main.js file in vue.js project .
import './animate.css'
Also if you like to import in template .
Inside the template you can do this.
<style src="./animate.css"></style>
Also have a look on css-loader package . what it does ?
Plugins are specific Vue packages that add global-level functionality to Vue, so if you aren't using a Vue plugin then you don't need to register it with Vue using Vue.use().
In general there isn't any issue using non-vue-specific packages via npm but if you need to register something globally, you can usually get away with simply attaching it to window like so:
window.x = require('package-name');
Unfortunately none of these answers worked for me what i ended up doing is
export default {
computed() {
x () {
return require('package-name')
}
}
}
And then use it as x.functionName() or whatever
There is better solution ... First import your package in main.js
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
import Vue from "vue";
import App from "./App.vue";
import "package-name";
After that's you code inside mounted method as javascript
<script>
export default {
mounted() {
const any = require("package-name");
// your code as normal js
},
};
</script>

How to use JQuery with ReactJS

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

Using velocity with jquery for IE8 in ES6

I am trying to use velocity together with jQuery (only for IE8 support) in an ES6 module. Consider this code:
import { Component } from 'react';
import ReactDOM from 'react-dom';
import jquery from 'jquery';
import velocity from 'velocity-animate';
export default class ScrollTo extends Component {
render() {...}
scrollToTop() {
velocity(ReactDOM.findDOMNode(this), 'scroll', { container: ReactDOM.findDOMNode(this.props.container) });
}
In IE8 velocity complains it cannot find jQuery. I checked in the source and it looks like velocity looks for jQuery on the window object but I'm importing it as a module.
Is there a way to instantiate/bind velocity with the imported jquery?
you can use ShimPlugin to shim jquery with webpack
see:
https://github.com/webpack/webpack/issues/192
or use ProvidePlugin to expose jquery to window, so that you don't have to import jquery every time you need it.
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
plugin ProvidePlugin This plugin makes a module available as variable
in every module. The module is required only if you use the variable.
Example: Make $ and jQuery available in every module without writing
require("jquery").

Categories