Use of jquery in React

I recently needed to use jquery while working on my markdown previewer project. I read it something that it can be done by using componentDidMount() react’s method. Is this correct way of doing it? I’m asking since i’m new to react and found little information about how to manipulate DOM in react.

I was trying to manipulate css of certain DOM elements for purpose of implementing features. Don’t know how to do that in react or if it can’t at all that i did in jquery/js, in vanilla js some is stuff needed to be “onload”, didn’t also know how to do that in react or in js since it’s all done in react. I also used jquery’s plugin “resizable” which doesn’t have vanilla js equivalent that i know off. And generally i want to know that: Is it correct way doing dom manipulation the way i did it here? Should i do it in vanilla or in react? Bottom line: What is correct way of doing this and where is my code lacking?

Of all of suggestions only this from that large group and this second one are applicable for my purposes.
But nothing beat simplicity of

$("#inner2").resizable({
	handles: 's',
	minHeight: 170
});

this line of code. Thus being said i can use vanilla javascript for most of my dom manipulation. The questions i’m asking that didn’t get answered is: Is it correct way of using jquery in manner i been using it, or is it ‘more’ correct using vanilla js for that same purpose?

You should never use React and jQuery in the same app, at least not if you are using JQ to manipulate the DOM. React wants complete and utter control over the DOM. If you start manipulating the DOM behind it’s back, then it can’t function properly. As I’ve said before, this is like putting your dinner in the microwave, and then putting the microwave in the oven.

Every time you try to manipulate the DOM outside of React, a puppy dies. It is bad. It is dangerous and a guarantee there is a better way to do it.

What are you trying to do? Change the CSS? You could have the CSS class passed to an element conditional on a variable, or use the variable in inline CSS. There are different ways to handle this. Please show us the JSX and explain what you are trying to do.

2 Likes

You really shouldnt mix JQuery and React, as Kevin said :wink:

To change CSS in React you would use the style attribute, like in this example:

const yourStyle = {"minHeight": 170}

<div style={yourStyle} />

Link to my previous post that shows code. One of the problems i’m tried to address in markdown previewer is how to add target="_blank" in generated link. There’s no a css way of doing it and only answer i found is in jquery and javascript. This also works for title attribute which is used for tooltips. Rest as i said to @camperextraordinaire it can be done in vanilla js. Problem occurs when something needs to be done onload i.e when doocument load. It can be done by using jquery inside componentDidMount() but i don’t know how to do it in plain js.

But that’s not a CSS issue, it’s an HTML issue.

But I think I understand now. You want links created dynamically in your editor to have this target added in the markdown viewer. That is an issue. So, I did what every great coder does - I googled it. I googled “marked.js add target blank to link” and got a list of ideas. The first one led me here. After about half the responses, there are a few good suggestions about how to override how marked.js creates links.

Never mix jQuery, React and DOM manipulation altogether.

Browsed it to oblivion searching for examples and none of them explains how to use them.
This code:

	marked.setOptions({
  breaks: true,
});

// INSERTS target="_blank" INTO HREF TAGS (required for codepen links)
const renderer = new marked.Renderer();
renderer.link = function (href, title, text) {
  return "<a target='_blank' href='${href}'>${text}` + '</a>";
}

where should i put it? In componentDidMount() doesn’t work, putting it globally doesn’t work, in constructor doesn’t work, it component itself throws errors. BTW i found plain js way which i just insert in componentDidMount().

document.querySelectorAll('a')
  .forEach(function(elem) {
    elem.setAttribute('target', '_blank');
  }); 

Since i don’t have previous experience in React and in marked library for React, solution without example implementation is no good for me. If you can tell me where to put said code that would be swell … Plus if it’s “forbidden” DOM manipulation in React by outside, why it’s then allowed by vanilla js or marked library in React?

I see this answer on that link:

var marked   = require('marked');
var renderer = new marked.Renderer();

marked.setOptions({
  ...
});

renderer.link = function( href, title, text ) {
  return '<a target="_blank" href="'+ href +'" title="' + title + '">' + text + '</a>';
}

marked(message, { renderer:renderer });

This has all the information I need. My current Markdown previewer (left over from the legacy FCC) doesn’t do this so I can add it.

The first line is not needed as CP takes care of that.

The next line:

var renderer = new marked.Renderer();

defines a new renderer object/class that I will tell marked.js use. I put it toward the top of the file.

The next line:

marked.setOptions({
  ...
});

are irrelevant as they set options - we don’t need it so I leave them out.

The next lines:

renderer.link = function( href, title, text ) {
  return '<a target="_blank" href="'+ href +'" title="' + title + '">' + text + '</a>';
}

They tell that new renderer how we want it to handle links. We are overriding the default handling and give it a new function to render the links. This can also go at the top of the code.

Lastly:

marked(message, { renderer:renderer });

shows me how to use the marked function and tell it to use my new renderer. I go to where my marked function is used. It was:

<div dangerouslySetInnerHTML={{__html: marked(this.state.markdown)}}></div>

and I change it to this:

<div dangerouslySetInnerHTML={{__html: marked(this.state.markdown, { renderer: renderer })}}></div>

Now it works. I added two things at the top and added a second parameter to my marked function. This is the final pen.

Look. I understand that you are frustrated. I was too. I still am, just on different subjects. This is complex stuff. But rather than deciding what you think is best even though it goes strongly against the advice of people that know better, why don’t you learn the right way? I had an old programming professor that used to say, “For every simple problem, the is a simple and elegant answer … that is wrong.” Just because it is easier, does not mean that it is better. There may be complications down the road that you do not understand that we do.

Never manipulate the DOM when working with React. Do not, do not, do not use jQuery at the same time. Period. Full stop. That is the wrong way to do it. There is a right way, but if you obsess about trying to prove that your kluged solution is OK, you won’t learn it.

It’s up to you - do you want to prove your point, or learn the right way. Please stop arguing and listen.

Part of learning is learning how to get information when you don’t know the answer. Web dev is very complicated and keeps changing so often the answer will not be laid out for you. I’m not saying that it is easy, just that it is what you need to learn how to do.

But yes, I can sympathize. I had many moments where I thought “wtf? Why does it have to be so complicated? Coudn’t I just do…?” But being an experienced learner, I know that I have to put my faith in the process. I didn’t have enough information to make an educated assessment. And now I understand why.

How 'bout vanilla js solution? Not even that?

I don’t understand the question. React is beyond vanilla (at least as I define it). Are you asking how to do the project without React or jQuery? It is certainly possible. But it’s not the point of the exercise.

Or are you saying there is something wrong with the code I provided? I don’t see anything un-vanilla about it. It’s used in this case in a React context, but all that code is standard JS.

I meant something like this: When you have function in js whom you bind in constructor
this.eraseIt= this.eraseIt.bind(this);
who look like smething

eraseIt(){
		counter2++;
		var editor = document.getElementById("editor");
		
		if(counter2===1){
				
			this.setState({
				messages: [],
			});
			
			editor.value="";
			document.getElementById("eraser").innerHTML = "Populate";
		}
		
		if(counter2===2){
			
			this.setState({
				messages: [placeholder],
			});
			
			editor.value = placeholder;
			document.getElementById("eraser").innerHTML = "Erase";
			counter2 = 0;
		}
		
	}

they you call it in like this

<div id="erase"><button id="eraser" onClick={this.eraseIt} type="button" className="btn btn-danger btn-lg" title="I erase & populate editor and preview" title="This is rather obvious isn't it? It's editor window Sherlock :D">Erase</button></div>

All js logic concerning dom manipulation is done in ths function which is plain js.

Look I have no interest in arguing with someone about whether or not it is a good idea to stick your hand in a fire with someone that still doesn’t completely understand what a hand or fire are.

DO NOT MANIPULATE THE DOM IN REACT. REACT DOES THAT FOR YOU. NEVER, NEVER, NEVER MANIPULATE THE DOM DIRECTLY WHEN WORKING WITH REACT OR YOU CAN BREAK REACT.

I have no interest in helping you learn the wrong way to do things. You seem quite capable of doing that on your own. You seem to have your mind made up so there is no point in my continuing this. I have given you a correct way to do it and you are still trying to convince me the wrong way is right. Whatever, man. Have a good life.

Okay, manipulating DOM in React is not a forbidden act. There are rare use cases for it and that’s why ref exists.
However, you should keep the DOM manipulation to a minimum (it is one of the reason React was created). So, adding full-fledged DOM manipulation library like JQuery in React doesn’t make sense.

The solution from @kevinSmith is better because it is using facilities provided by marked library. The problem originated from how marked was rendering; so, it makes sense to fix the problem there.

Apparently, you are not using React the way it is supposed to be used. The reliance on global counter, single component handling everything, and sheer amount of DOM manipulating are the evidence. If you’ve decided to use React, adapt yourself to React ways. If you don’t know React ways, learn from tons of online resources.

I don’t know the specifics of that use case, but I have heard it mentioned. But that is a very specific case that is built into React and therefore React knows how to handle it.

From the React documentation

Managing focus, text selection, or media playback.
Triggering imperative animations.
Integrating with third-party DOM libraries.

Yes, like I said, it is something that React knows how to handle. It is a very specific use. And even then React more than once tells you not to use it too much and there is probably a better solution.

I’m not saying that you can’t use refs in React as outlined in the React docs. I’m saying that that is an extreme case and people shouldn’t use that as an excuse to do other DOM manipulations (not that you’re suggesting that). My statement “Don’t manipulate the DOM” may be hyperbole, but it is very, very useful hyperbole for beginners. They can learn the exceptions later.

FYI, I didn’t object to your statement on prefer React way over DOM manipulation. Certainly, OP’s problem doesn’t need DOM manipulation.

Cool, that’s how I understood it. I got the sense that you knew the distinction, but wanted to make sure others wouldn’t understand. I should probably learn more about refs and React though, thanks for reminding me that I need to check that out.