Yes, I would say there are disadvantages to using jQuery in React.
The VDOM diffing algorithm will get confused
This is one that you mentioned. Yes, it will be fine if you use only read-only
attributes, but unless you're targeting older browsers something like document.querySelector
would be lighter weight.
Every depedency you're bringing in, especially as one as large as library, should be meticulously vetted. See the website obesity epedemic for details.
In addition, the idea of "I will only use it for reading and let React do the rest" will add a significant layer of confusion to your code, as we'll see in the next example.
You abandon the patterns of React
In my opinion, the bigger issue is abandoning the patterns of React. To describe React in one sentence, I would say:
React is a component-based library used to generate HTML, CSS, and JavaScript functionality derived from state
inputs.
Let's say I have a simple UserProfile
component. This component will have some data about the user, including a switch to receive push notifications or not:
// Please note this is simplified pseudo-code, and will likely not work
class UserProfile extends Component {
state = {
name: 'Bob',
profilePic: 'someurl.com/profile-pic',
isReceivingNotifications: false
}
updateReceivingNotifications = () => {
this.setState({ isReceivingNotifications: !this.state.isReceivingNotifications })
}
render() {
const { name, profilePic, isReceivingNotifcations } = this.state;
return (
<div>
<h2>{name}</h2>
<img src={profilePic} />
<input type="checkbox" checked={isReceivingNotifications} onChange={this.updateReceivingNotifications} />
</div>
);
}
}
Simple, the component presentation is derived from the state of the component. If the isReceivingNotifcations
is true, then the checkbox will be checked.
Let's look at this same example with the proposed design pattern:
class UserProfile extends Component {
state = {
name: 'Bob',
profilePic: 'someurl.com/profile-pic',
isReceivingNotifications: false
}
componentDidMount() {
const checkBox = document.getElementById('my-checkbox');
const that = this;
// Use a regular function to bind the this context to the checkbox instead of component
checkBox.addEventListener('change', function() {
if (this.checked) {
that.setState({ isReceivingNotifcations: true });
} else {
that.setState({ isReceivingNotifcations: false });
}
});
}
render() {
const { name, profilePic, isReceivingNotifcations } = this.state;
return (
<div>
<h2>{name}</h2>
<img src={profilePic} />
<input
type="checkbox"
checked={isReceivingNotifications}
id="my-checkbox"
/>
</div>
);
}
}
The first is much cleaner, no matter how you format this with jQuery or whatever DOM manipulation library you would use.
This is a contrived example, but every time I've seen some version of this in real life it's been quite a mess.
In the end, why?
Just take a bit of time and learn React design patterns. I'd suggest thinking in React. jQuery should be a last resort, as you're using React for a reason i'd assume.
One exception to this is jQuery libraries you use in React
In this case, you have no other option other than rewriting the library. As highlighted in this article you should write a wrapper component to make it React compliant.