简体   繁体   中英

React-JS - Issue with a jQuery Lightbox

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM