在 React 组件中如何嵌入并调用外部 JavaScript 函数?

3

我正在尝试将这张地图整合到一个已有的Grails/React项目中。

更新后的代码:

index.js

ReactDOM.render((

    <Router history = {browserHistory}>
        <Route path="/" component={CreateAccount}/>
        <Route path="/menu" component={Menus}/>
        <Route path="/discover" component={DiscoverApp}/>

        <Route path="/NorthAmerica" component={northAmerica}/>
        <Route path="/SouthAmerica" component={southAmerica}/>
        <Route path="/Europe" component={europe}/>
        <Route path="/Asia" component={asia}/>
        <Route path="/Africa" component={africa}/>
        <Route path="/Australia" component={australia}/>
    </Router>

), document.getElementById('root'));

index.gsp

<head>
        <title>Food App</title>
    <link rel="stylesheet" href="${resource(dir: 'css', file: 'text.css')}" type = "text/css">
    <link rel="stylesheet" href="${resource(dir: 'css', file: 'jquery-jvectormap-2.0.3.css')}" type = "text/css" media="screen">
<javascript src="/js/jquery-3.1.1.js" />
<javascript src="jquery-jvectormap-2.0.3.min.js" />
<javascript src="jquery-jvectormap-world-mill-en.mins.js" />
</head>
<body>
<div id="root" align="left"></div>
<br/>
<asset:javascript src="bundle.js"/>
</body>
</html>

并且

import React, { Component } from 'react';
import {Link} from 'react-router';
import $ from 'jquery';
import ReactDOM from 'react-dom';

class NorthAmerica extends Component {

    componentDidMount() {
        const el = ReactDOM.findDOMNode(this.display);
        $(el).vectorMap({map: 'world_mill_en'});
    }

    render(){
        return(
            <div>
                <h1>NORTH AMERICA MAP PLACE-HOLDER</h1>
                <li><Link to="/discover">DISCOVER</Link></li>
                <div
                    ref={display => this.display = display}
                />
            </div>
        )
    }
}

export class northAmerica extends React.Component{
    render(){
        return(<NorthAmerica/>);
    }
}

有什么建议吗?谢谢!

更新:

页面现在已经加载完毕...但是地图应该出现的位置只是一个空白的div。我在控制台中收到了以下错误:

Uncaught TypeError: (0 , _jquery2.default)(...).vectorMap is not a function
    at NorthAmerica.componentDidMount (bundle.js?compile=false:12781)
    at bundle.js?compile=false:26803
    at measureLifeCyclePerf (bundle.js?compile=false:26613)
    at bundle.js?compile=false:26802
    at CallbackQueue.notifyAll (bundle.js?compile=false:9088)
    at ReactReconcileTransaction.close (bundle.js?compile=false:31708)
    at ReactReconcileTransaction.closeAll (bundle.js?compile=false:5241)
    at ReactReconcileTransaction.perform (bundle.js?compile=false:5188)
    at ReactUpdatesFlushTransaction.perform (bundle.js?compile=false:5175)
    at ReactUpdatesFlushTransaction.perform (bundle.js?compile=false:1438)
3个回答

1

refs在React中是必需的,以便在React组件内获取底层DOM。一旦该元素在组件中可用,就可以在jQuery元素上调用第三方库函数,例如vectorMap。以下是一个React组件示例,假设所有相关依赖库都可用于呈现DOM。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';

class NorthAmerica extends Component {
  componentDidMount() {
    const el = ReactDOM.findDOMNode(this.display);
    $(el).vectorMap({map: 'world_mill_en'});
  }

  render() {
    return <div>
      <h1>World Map</h1>
      <div 
        ref={display => this.display = display} 
        style={{width: '600px', height: '400px'}} 
      />
    </div>;
  }
}

/*
 * Render the above component into the div#app
 */
ReactDOM.render(<NorthAmerica />, document.getElementById('app'));

这是一个例子codepen,由于我无法提供适当版本的jqueryvectormap库,因此它无法正常工作。
上述CodePen的导出和修改版本可以工作。git clone然后在浏览器中打开index.html

哇,太棒了。我只有一个问题。对于这个项目,我们正在从每个大陆的各种js文件中导出到一个index.js文件,该文件呈现给DOM。我应该在哪里链接源jvector文件和jquery文件?还是HTML文件?这是一个grails项目。由于我使用了多个js文件,所以我应该从每个文件中调用导出吗?谢谢。 - Strobe00
我不确定我是否理解你所说的“从各种js导出”的意思。但是,既然你正在使用React,你可以创建一个包含所有这些子组件的父组件,比如WorldMap组件。至于像jquery和jvectormap库这样的静态资源,你可以使用grails asset-pipeline,它已经内置在最新的Grails应用程序中了。 - dmahapatro
我已经实现了你的代码,并更新了问题,同时也附上了控制台错误信息。现在我完全不知道该怎么办了 :(感谢你的帮助,非常感激。 - Strobe00
请确保使用此库。请参考Github上的示例应用程序。 - dmahapatro
出于某种原因,结果证明,我只需要将$(el)...更改为jQuery(el)...就可以使您的代码正常工作...再次感谢您的帮助! - Strobe00

0
你应该使用 React 的组件生命周期方法来执行你的函数,而不是尝试渲染内联脚本标签。尝试从 render 方法中删除内联脚本,并添加一个 componentDidMount 方法:
componentDidMount() {
  $(your jQuery function here);
}

假设您正在使用webpack,您可能希望将jquery声明为外部模块,但是上述代码至少可以让事情开始运行。


0

改为:

let NorthAmerica = React.createClass({

您可以立即导出此内容:

export default class NorthAmerica extends React.Component {

然后删除你最后的代码块:

export class northAmerica extends React.Component{
    render(){
        return(<NorthAmerica/>);
    }
}

你看不到任何东西的原因是因为你的NorthAmerica组件还没有被添加到DOM中。尝试:

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

在这里,'root'应该替换为您的index.gsp中一个div的名称,该div是所有React内容的容器,请参考enter link description here

为了使其正常工作,您需要进行额外的导入:

import ReactDOM from 'react-dom';

只有在您从另一个文件中使用NorthAmerica时才需要导出。如果您还没有这样做,那么它是不必要的,请参见此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接