我正在尝试使用一个使用大量jQuery的Layout / Template的项目。
我已经学会了将模板与ReactJS Project集成在一起,但是,我正在寻找一种可以完全替代jQuery的解决方案。
我的解决方案之一是在React的ComponentDidMount()
或Render()
函数中使用jQuery函数。
这种方法正确吗?这是正确的方法吗?
我在下面附上了一个小例子:
import React, { Component } from 'react';
import '../stylesheets/commonstyles.css';
import '../stylesheets/bootstrap-sidebar.css';
import '../stylesheets/sidebar1.css';
import $ from 'jquery';
class NavBar extends Component {
constructor(props){
super(props);
this.openSidebar = this.openSidebar.bind(this);
}
openSidebar(){
console.log('hello sidebar');
}
componentWillMount(){
$(document).ready(function () {
$('#sidebarCollapse').on('click', function () {
$('#sidebar').toggleClass('active');
});
$('.search-btn').on("click", function () {
$('.search').toggleClass("search-open");
return false;
});
});
}
这是我的Render
函数。
{/* <!--- SIDEBAR -------> */}
<div class="wrapper" style={{paddingTop:60}}>
{/* <!-- Sidebar Holder --> */ }
<nav id="sidebar">
<div class="sidebar-header">
<h3>Dashboard</h3>
<strong>BS</strong>
</div>
<ul class="list-unstyled components">
<li class="active">
<a href="#homeSubmenu" /*data-toggle="collapse" */ aria-expanded="false">
<i class="ti-home"></i>
Home
</a>
<ul class="collapse list-unstyled" id="homeSubmenu">
<li><a href="#">Home 1</a></li>
<li><a href="#">Home 2</a></li>
<li><a href="#">Home 3</a></li>
</ul>
</li>
<li>
<a href="#" style={{color:"white"}}>
<i class="ti-align-justify" ></i>
About
</a>
<a href="#pageSubmenu" /*data-toggle="collapse" */ aria-expanded="false" style={{color:"white"}}>
<i class="ti-text"></i>
Pages
</a>
<ul class="collapse list-unstyled" id="pageSubmenu">
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 3</a></li>
</ul>
</li>
<li>
<a href="#" style={{color:"white"}}>
<i class="ti-paragraph"></i>
Portfolio
</a>
</li>
<li>
<a href="#" style={{color:"white"}}>
<i class="ti-control-play"></i>
FAQ
</a>
</li>
<li>
<a href="#" style={{color:"white"}}>
<i class="ti-share-alt"></i>
Contact
</a>
</li>
</ul>
</nav>
{ /* <!-- Page Content Holder --> */ }
<div id="content">
</div>
</div>
答案 0 :(得分:8)
这种方法正确吗?这是正确的方法吗?
不。没有正确的方法,也没有正确的方法同时使用jQuery和React / Angular / Vue。
原因是jQuery通过选择元素并在元素中添加/删除元素来操纵DOM。
其他框架不操纵DOM,而是从数据生成DOM,并在数据更改时重新生成。
问题是,jQuery不了解React的存在和动作,而React不了解jQuery的存在和动作。这必然会导致应用程序损坏,充满破解和变通办法,难以维护,更不用说您必须加载两个库而不是一个。
解决方案:不能同时使用jQuery或React。
答案 1 :(得分:2)
这种方法正确吗?这是正确的方法吗?
不。不要使用jQuery将事件侦听器附加到由React创建和管理的DOM元素上。在您的代码段中使用onClick'. I could not find
#sidebarCollapse`。可能看起来像这样。
<button id="sidebarCollapse" onClick={state => this.setState({ collapsed: !state.collapsed })>Collapse</button
<nav id="sidebar">
的类可能取决于此状态
<nav id="sidebar" className={ this.state.collapsed ? "": "active" } >
您会注意到,您将正在运行的操作(如添加删除类,属性和其他DOM操作)移交给React,并简单地声明了事物必须如何对状态变化做出反应。在这种情况下,如果尝试运行jQuery操作,则UI可能最终处于不一致状态。
迁移可以这样完成:用React替换部分UI元素。例如,起初您可以做,
<!-- rest of your existing jQuery based code -->
<header id="reactManagedNavbar">
<!-- Nothing here. React will take care of DOM Elements here -->
</header>
<!-- rest of your existing jQuery based code -->
React端看起来像这样,
// main.js
ReactDOM.render(<MyNavBar />, document.getElementById('reactManagedNavBar'))
// MyNavBar.js could have the react components
通过这种方式,您可以逐步迁移到React并保持jQuery并排。只是不要互相操纵DOM元素。
有时,您需要在React组件中使用jQuery插件(动画,可视化图表等)。使用refs!
class MyJQueryDependingComp extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// this.myRef.current is the dom element. Pass it to jQuery
}
render() {
return (
{/* rest of React elements */}
<div ref={this.myRef} />
{/* rest of React elements */}
);
}
}
再次,避免在React中接触jQuery的DOM,反之亦然。
答案 2 :(得分:0)
jQuery和react仅在彼此不交互时才能很好地结合在一起。如果选择使用jQuery,请仅使用jQuery来操纵dom,而不能同时使用两者。一种方法是在index.html中的react Js文件之外使用jQuery 请注意:仅当您首先加载查询的页面时,此功能才有效
答案 3 :(得分:0)
我建议您在webpack.config中使用提供程序插件:
使用起来真的很简单,它允许您在所有项目中使用jquery,而无需在每个文件中导入包:
更多信息文档: https://webpack.js.org/plugins/provide-plugin/?
因此您只需要在webpack.config文件中添加此插件即可
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
});