I have this React component that renders images from a DB. The component is fetching successfully the images. But the jQuery gallery isn't working. When the component page starts to load, there appears an error's message:
TypeError: __WEBPACK_IMPORTED_MODULE_3_jquery___default(...)(...).simpleLightbox is not a function
It is the line pointed as the errors' cause:
$('.gallery a').simpleLightbox();
Here is the plugin's page: https://github.com/andreknieriem/simplelightbox
Here is my React Component:
/* global $ */
import React, { Component } from 'react'
import axios from 'axios'
import $ from 'jquery'
const URL_INTERIORS = 'http://localhost:3001/interiors';
class Interiors extends Component {
constructor(props) {
super(props);
this.state = {
interiors: [],
interiorsPhotos: [],
};
this.activateLightBox = this.activateLightBox.bind(this);
}
componentDidMount() {
axios.get(URL_INTERIORS)
.then(res => {
this.setState({
interiors: res.data[0],
interiorsPhotos: res.data[0].photos
})
})
this.activateLightBox();
}
componentWillUpdate() {
this.activateLightBox();
}
activateLightBox() {
$(function () {
//Here is the line pointed as the errors' cause:
$('.gallery a').simpleLightbox();
})
}
render() {
const renderPhotos = currentItems.map((photo, index) => {
return (
<a className="gal-img-js" href={`../images/${photo}.jpg`} key={index}>
<img src={`../images/${photo}_thumb.jpg`} alt="" />
</a>
)
});
return (
<div className="gallery images-box-1 big">
{ renderPhotos}
</div>
</div>
);
}
}
export default Interiors
The jQuery is calling from a <script>
tag in the end of the header
in the index.html file.
//...rest of the code ommited
<title>My website</title>
<script type="text/jsx" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/jsx" src="simplelightbox-master/dist/simple-lightbox.js"></script>
</head>
//...rest of the code ommited
Does anybody know how to solve it?
You have to use the plugin provider in webpack to handle the variables:
I use something similar in my webpack.config
new webpack.ProvidePlugin({
jQuery : 'jquery',
$ : 'jquery',
}
I also add the jquery script in my index.html
depending of your webpack version is the method that you have to use:
Check the Docs here https://webpack.js.org/plugins/provide-plugin/
I have reproduced the example in the demo in the library you provided and it happens to has npm package install so you can install it to react and you don't have to implement it in html here is the code it's working fine
import React, { Component } from 'react';
import $ from 'jquery';
import './App.css';
$('.gallery a').on('error.simplelightbox', function (e) {
console.log(e); // some usefull information
});
class App extends Component {
render() {
return (
<div className="App">
<div className="gallery">
<a href="images/image1.jpg" className="big"><img src={require('./images/thumbs/thumb1.jpg')} alt="image1" title="Beautiful Image" /></a>
<a href="images/image2.jpg"><img src={require('./images/thumbs/thumb2.jpg')} alt="image2" title="image2"/></a>
<div className="clear"></div>
</div>
</div>
);
}
}
export default App;
and here is your code after modification :
// don't forget to npm install simplelightbox
import React, { Component } from 'react'
import axios from 'axios'
import $ from 'jquery' // also don't forget to install jquery or implement it in html
$('.gallery a').on('error.simplelightbox', function (e) {
console.log(e); // some usefull information
});
const URL_INTERIORS = 'http://localhost:3001/interiors';
class Interiors extends Component {
constructor(props) {
super(props);
this.state = {
interiors: [],
interiorsPhotos: [],
};
}
componentDidMount() {
axios.get(URL_INTERIORS)
.then(res => {
this.setState({
interiors: res.data[0],
interiorsPhotos: res.data[0].photos
})
})
}
render() {
const renderPhotos = currentItems.map((photo, index) => { // i suppose you already have access to currentItems from props or state
return (
<a className="gal-img-js" href={`../images/${photo}.jpg`} key={index}>
<img src={`../images/${photo}_thumb.jpg`} alt="" />
</a>
)
});
return (
<div> // you forgot div tag here
<div className="gallery images-box-1 big">
{ renderPhotos}
</div>
</div>
);
}
}
export default Interiors
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.