添加 jQuery 插件在 React 应用程序中不起作用; “类型错误:this.$el.chosen 不是一个函数”

问题描述 投票:0回答:4

我正在学习 React,并且正在关注 集成其他库章节。我尝试了他们建议的相同方法,但出现以下错误:

TypeError: this.$el.chosen is not a function
Chosen.componentDidMount
src/App.js:18

  componentDidMount() {
    this.$el = $(this.el);
>   this.$el.chosen();
  }

React 网站提供了 示例 codepen,他们在依赖项中添加了 jQuery 并选择了插件 .js 文件。我添加了 jQuery 并在 index.html 中选择了库 .js 文件,还使用

npm install jquery --save
添加了 jQuery,以便可以在 App.js 中导入它。

###index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.6.2/chosen.jquery.min.js"></script>
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
  </body>
</html>

###App.js

import React, { Component } from 'react';

import $ from 'jquery';

class Chosen extends Component {

  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();
  }

  componentWillUnmount() {
    this.$el.chosen('destroy');
  }

  render() {
    return (
      <div >
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

function Example() {
  return (
    <Chosen >
      <option >vanila</option>
      <option >strawberry</option>
      <option >chocolate</option>
    </Chosen>
    );
}


class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <section>
          <Example/>
        </section>
      </div>
    );
  }
}

export default App;

###index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

为什么我会收到此错误以及如何修复它?

reactjs jquery-plugins
4个回答
3
投票

按照以下步骤让它工作(使用 create-react-app 创建项目后)

npm install jquery --save
npm install chosen-js --save

将其添加到 node_modules/chosen-js/chosen.jquery.js 的第 1 行

import jQuery from 'jquery'

根据这个答案

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import $ from 'jquery'
import "chosen-js/chosen.css";
import "chosen-js/chosen.jquery.js";

class Chosen extends React.Component {


  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();

    this.handleChange = this.handleChange.bind(this);
    this.$el.on('change', this.handleChange);
  }

  componentDidUnmount() {
    this.$el.off('change', this.handleChange);
    this.$el.chosen('destroy');
  }

  handleChange(e) {
    this.props.onChange(e.target.value);
  }

  render() {
    return (
      <div>
        <select className="Chosen-select" style={{width: "200px"}} ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

function Example() {
  return (
    <Chosen className="chosen-container chosen-container-single" onChange={value => console.log(value)}>
      <option>vanilla</option>
      <option>chocolate</option>
      <option>strawberry</option>
    </Chosen>
  );
}


class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
          <Example/>
        </p>
      </div>
    );
  }
}

export default App;

1
投票

我在阅读文档时也遇到了同样的问题。但我不更新“node_modules/chosen-js/chosen.jquery.js”文件,而是更喜欢使用 ProvidePlugin 在 webpack.config.js 中注入隐式全局变量

但是当我们使用 create-react-app 创建应用程序时,我们没有找到 webpack.config.js 文件。 您将需要弹出反应应用程序。但在弹出应用程序之前,您应该首先阅读以下链接(如果您是高级用户并且对默认配置不满意)。

链接:- https://github.com/satendra02/react-chrome-extension/wiki/What-happens-when-you-eject-Create-React-App https://medium.com/curated-by-versett/dont-eject-your-create-react-app-b123c5247741

您将需要运行以下命令来弹出 React 应用程序,因为此命令将从您的项目中删除单个构建依赖项,并将所有配置文件和传递依赖项(webpack、Babel、ESLint 等)复制到您的项目中作为 package.json 中的依赖项

npm 运行弹出

安装依赖项

npm install jquery selected-js --save

现在编辑您的 webpack.config.js 文件并更新配置对象,如下所示

return {
    ...
    module: {
        ...
    },
    plugins: [
        ...
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        }),
    ]
    ...
}

Chosen.js

import React from 'react';
import $ from "jquery";
import "chosen-js/chosen.css";
import "chosen-js/chosen.jquery.js";

class Chosen extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();

    this.handleChange = this.handleChange.bind(this);
    this.$el.on("change", this.handleChange);
  }

  componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger("chosen:updated");
    }
  }

  componentWillUnmount() {
    this.$el.off("change", this.handleChange);
    this.$el.chosen("destroy");
  }

  handleChange(e) {
    this.props.onChange(e.target.value);
  }

  render() {
    return (
      <div>
        <select className="Chosen-select" ref={(el) => (this.el = el)}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

0
投票

这似乎是一个与依赖性有关的问题。

我注意到您将 JQuery 及其选择的插件包含在 CDN 中,这意味着它是全局声明的。但是在

App.js
的第三行你
import $ from 'jquery';
可能会在本地引入JQuery。根据我的经验,React 会将 $ 引用到本地 JQuery,而该插件不包含该插件。

我建议你可以尝试注释掉

import $ from 'jquery'
然后再试一次。

祝你好运!


0
投票

使用

window.$("#infomodal").modal("hide");
© www.soinside.com 2019 - 2024. All rights reserved.