如何在 React 组件中使用 jQuery
介绍
有时,当我们构建大型应用程序时,我们可能希望使用 jQuery 插件或 jQuery 功能来完成 React 中无法实现的操作。使用 React 的优点是每个组件都可以独立于其他组件维护自己的状态。
由于许多 Web 应用都是使用 jQuery 开发的,因此我们可能希望 React 组件与 jQuery 应用集成。例如,我们可能希望在 React 应用程序中显示一些数据。同样,我们可能有一个现有的 jQuery 应用,并希望 React 应用将数据发送到 jQuery 应用以在页面上呈现。
应用程序的 React 端与 jQuery 之间的通信实际上很容易实现。在本指南中,我们将介绍三种不同的方法来实现这一点:
- 从 React 引用 jQuery 上下文
- 使用辅助类,传递给 React
- 使用传递给 React 的发布者 / 订阅者对象
从 React 引用 jQuery 上下文
此方法涉及在我们最初创建 React 组件时将 jQuery 上下文的副本(即 $(this))传递给构造函数中的 React 组件。这允许 React 操作我们现有的 UI 元素。
我们的 jQuery 应用最初使用对 React.createElement 的调用并将 jQuery 应用的上下文传递给组件构造函数来创建 React 组件。然后,组件可以将引用(可通过 props 参数获得)存储在其状态中,并使用它来更新网页上的关键元素。这允许组件更改其自身组件区域之外的网页元素。
下面是代码:
ReactDOM.render(React.createElement(MyjQueryReactComponent, { context: $('body') }), document.getElementById('root'));
});
在上面的例子中,我们可以看到组件最初是如何创建的。我们将对 jQuery body 元素的引用传递给组件的构造函数。然后可以通过组件构造函数的 props 访问它。
下面是我们的 React 组件,它存储了 jQuery 上下文。它还可以直接更新 UI 元素,如下所示。我们还可以看到构造函数接受一个“props”参数,该参数将具有我们在创建时传递的 jQuery 上下文。此上下文实际上存储在组件的状态中。
class MyjQueryReactComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
context: props.context
};
this.onClick = this.onClick.bind(this);
}
onClickBtn() {
// Getting ref to JQuery object from our parent app.
var myDomEl = this.state.context.find('#myDomEl');
// Update color of our element.
myDomEl.css('background-color', 'green'));
}
render() {
return (
<div className='alert alert-success' role='alert'>
<h3>Hello there!</h3>
<button type='button' className='btn btn-default' onClick={ this.onClickBtn }>Click to Update!</button>
</div>
);
}
}
使用辅助类,传递给 React
此方法涉及将引用 JavaScript 对象传递给 React 组件,该组件将充当 React 组件和现有 Web 应用程序之间的中介。然后,React 组件可以从这个中间 javascript 类请求数据,甚至要求它使用更新的数据更新页面的某些部分。因此,jQuery Web 应用程序可以控制其自己的 UI 部分。同样,React 组件也可以控制其自己的 Web 元素部分。React 组件获取 JavaScript 辅助类的副本,以便它可以从父 jQuery 应用程序获取通知,还可以向主 Web 应用程序(即在其自身范围之外)请求任何更新。
这种方法的主要优点是,我们可以明确区分 React 组件对页面上 UI 元素的责任和 jQuery 应用对自己 UI 元素的所有权。React 组件可以维护其自己的页面部分,并让 jQuery 拥有剩余部分。React 组件可以通过帮助程序类发送请求,要求在其控制范围之外对 UI 进行任何更新,jQuery Web 应用可以做出相应的响应。
下面是实例化 React 组件并将辅助类传递给它的示例。
ReactDOM.render(React.createElement(MyjQueryReactComponent, { context: UIHelper }), document.getElementById('root'));
现在我们可以看到,我们不再像上一个示例那样传递 jQuery 上下文本身,而是传递对 JavaScript 中间类的引用。这个中间类具有用于更新不同 UI 元素以及 React 组件范围之外的状态的方法。
UIHelper类如下所示:
var UIHelper = {
getBgColor: function(parent, callbackfn) {
callbackfn($('#elm').css('background-color'), parent);
},
setBgColor: function(color) {
$('#elm').css('background-color', color);
}
};
我们可以看到,上面的类只包含几个处理页面上 UI 元素背景颜色的方法。我们还可以获取/读取此元素的当前背景颜色值,甚至更新其背景颜色。
与上一个 React 组件示例类似,我们可以将外部 Web 应用的上下文存储在 React 组件的状态中。不过,这一次,上下文不再是 jQuery 对象的引用,而是存储对辅助 JavaScript 类(即 UIHelper)的引用。
下面是代码:
class MyjQueryReactComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
context: props.context
};
this.onBtnClick = this.onBtnClick.bind(this);
}
onBtnClick() {
this.state.context.getBgColor(this, function(color, self) {
self.state.context.setBgColor('green');
});
}
render() {
return (
<div className='alert alert-success' role='alert'>
<h3>Hi there!</h3>
<button type='button' className='btn btn-default' onClick={ this.onBtnClick }>Click to Update!</button>
</div>
);
}
}
我们可以看到,在上面的代码中,我们存储了对 UIHelper 的引用,它在 React 组件的状态中被称为 props.context。一旦用户点击 React 组件中的按钮,我们就会通过上下文调用 UIHelper 类来获取 UI 元素的当前背景颜色。然后我们再次调用 UIHelper 来更新背景颜色。
使用传递给 React 的发布者 / 订阅者对象
将 React 与现有 jQuery 应用程序集成的另一种方法是通过 pubsub 模型。这使组件能够监视来自外部 Web 应用程序的更新并发送更新。例如,当客户端与现有 Web 应用程序交互时,可能会发生某些事件触发方法,然后这些方法会被发送到 React 组件,以便它可以相应地刷新其 UI。
现在,我们已将 UIHelper Javascript 类替换为发布/订阅模型。因此,React 组件可以获知来自外部 Web 应用程序的事件,并更新其内部状态和 UI 控件。
让我们举一个简单的例子。每当用户点击现有 jQuery 应用程序中的按钮时,我们都会向其间的 Javascript 类的所有订阅者发送一个事件,并让它们做出相应的响应。
我们可以使用 pub/sub 帮助类来做到这一点
var PubSubHelper = {
subscribers: [],
subscribe: function(parent, callbackfn) {
this.subscribers.push({ parent: parent, callbackfn: callbackfn });
},
bgColor: function(name) {
// Inform subscribers of the event.
this.subscribers.forEach(function(subscriber) {
subscriber.callbackfn(name, subscriber.parent);
});
}
};
在上面的类中,我们有一个订阅方法,客户端可以通过该方法订阅来自父应用程序的事件通知。因此,每当现有应用程序调用 bgColor 方法时,所有订阅者都会收到更改通知,从而有机会相应地更新其 UI。
我们举个例子,现有应用每 2 秒更新一次页面上 UI 元素的背景颜色。它会将背景颜色从绿色更新为红色。以下是代码:
$(function() {
setTimeout(function() {
ReactDOM.render(React.createElement(MyjQueryReactComponent, { context: PubSubHelper }), document.getElementById('root'));
}, 0);
// Change the element bgcolor every 2 seconds.
setInterval(function() {
var elm = $('#elm');
var bgColor = elm.css('background-color') === 'rgb(255, 255, 0)' ? 'red' : 'green';
// Change element color
elm.css('background-color', bgColor);
// Inform subscribers.
PubSubHelper.bgColor(bgColor);
}, 2000)
});
在上面的例子中,UI 元素的背景颜色更新间隔为两秒。React 组件通常无法识别元素背景颜色的变化。它也没有直接访问 UI 元素本身的方法。这是因为该元素实际上是 React 组件范围之外的 div。
但是,使用 pubsub 模型,React 组件可以在元素背景颜色更新时收到通知。React 组件可以做出反应并相应地更新其自己的 UI 元素。
React 组件可以监听主应用中的事件,如下例所示。我们还可以看到构造函数现在存储了对应用上下文(pubsub 模型)的引用。这与前面的示例类似,但上下文现在是 pub/sub 模型,而不是 UIHelper 类。
我们还可以调用 subscribe 方法来监听来自现有 Web 应用的事件。在下面的示例中,我们将处理 onBgColor 事件,以根据触发的事件更新 React 组件的 UI。
class MyjQueryReactComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
bgColor: 'red',
context: props.context
};
// Listen to bgColor events.
this.state.context.subscribe(this, this.onBgColor);
}
onBgColor(bgColor, that) {
// Change the state value for bgColor.
that.setState({ bgColor: bgColor });
}
render() {
return (
<div className='alert alert-success' role='alert'>
<h3>Hello, from React!</h3>
<span className={ 'icon ' + (this.state.bgColor === 'red' ? 'icon-danger' : 'icon-success') + ' p-3' }>
{ this.state.bgColor }
</span>
</div>
);
}
}
在上面的示例中,我们的 React 组件有一个标题/消息以及一个包含警告/成功消息的 span 元素。消息根据当前状态 bgColor 的值更新其标签以及 bgColor。状态 bgColor 从 onBgColor 事件中获取一个值,该事件被外部应用程序中的 pub/sub 类作为回调方法调用。
我们还可以看到 onBgColor 回调函数获取了 bgColor 名称以及对 React 组件上下文的引用。我们希望发布/订阅模型将此信息发送给我们,因为我们事件处理程序的当前上下文来自发布/订阅类,而不是来自我们的 React 组件。要访问 this.state,我们必须引用父上下文 that.state。
从外部直接调用 React 组件方法
除了我们上面讨论的 React 组件和 jQuery / 外部应用程序之间通信的方法之外,我们还可以通过调用 React 组件本身的方法以反向的方式进行通信,即从 jQuery 到 React。
当我们的 React 组件在屏幕上呈现时,它会返回该组件的一个实例。我们可以利用这个实例并调用 React 组件中的方法。因此,我们可以从外部访问 React 组件,并且通过调用 React 组件上的方法,我们可以更新 React 应用程序的状态和用户界面。
让我们看一个例子:
<button id='showBtn' type="button" class="btn btn-primary">Show</button>
<button id='hideBtn' type="button" class="btn btn-primary">Hide</button>
<div id="root"></div>
<div id="output"></div>
我们还在我们的 div 中渲染 React 组件,如下所示:
var myComponent = ReactDOM.render(React.createElement(MyComponent), document.getElementById('root'));
调用 render 命令后,我们将 React 组件实例的副本存储在名为 myComponent 的变量中。这就是我们调用 React 组件内部方法的方式。
我们还将更新 jQuery 方法来显示/隐藏按钮。
$(function() {
$('#showBtn').click(function() {
$('#output').text('');
myComponent.show('Hello World!', function(text) {
$('#output').text(text);
});
});
$('#hideBtn').click(function() {
myComponent.hide();
});
});
最后我们有了我们的 React 组件,如下所示:
class MyjQueryReactComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: '',
visible: false
};
this.onSaySomething = this.onSaySomething.bind(this);
};
show(text, callback) {
this.setState({ visible: true, text: text, callback: callback });
}
hide() {
this.setState({ visible: false });
}
onSaySomething() {
this.state.callback('Hello from
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~