Access dom element with reactjs - javascript

I have an AntD component, and i don't have access to the html markup to use useRef to apply a style to next class , depending by a condition:
span.ant-descriptions-item-content
This is why i used:
if(my condition) {
document.querySelector('span.ant-descriptions-item-content').style.background="red"
}
demo: https://codesandbox.io/s/basic-ant-design-demo-fdwxd?file=/index.js
It is ok to use native ways of accessing dom element like document.querySelector, or exists another method to do this in my case?

It is generally not recommended to mix different tools that handle changing how the web page is rendering. This can cause unpredictable behavior and components not updating correctly. If you want to change the appearance of a component using React you should be rendering that component within React.

Related

How do popular React component libraries like MUI/Bootstrap change classNames on elements?

https://jquense.github.io/react-widgets/docs/Multiselect/
If you look at the multiselect at this link, and inspect element, when you click into the input you'll see the main div element change classnames from 'rw-popup-container' to 'rw-popup-container rw-slide-transition-exited'. The class 'rw-slide-transition-exited' contains display=none in css which makes the dropdown disappear.
This process of adding/subtracting classnames is extremely snappy and common among various React libraries like MUI/React Bootstrap. You can inspect the source HTML and see they are all doing it. How, exactly, are they doing this? I've looked through the source JS but I can't figure it out. It doesn't appear to be jQuery addClass()/removeClass() and they are doing conditional rendering in React (which is laggy from personal experience).
As you said, this is pretty commong in React libraries (VueJs and Angular libraries as well).
All the modern javascript frameworks have a way to conditionally set the styles of a component, and they just refresh that attribute, there's no need to re-render everything.
Particullary for React, you can unse the "className" proeprty for that, instead of passing an string you can pass a function, and that will dynamically change the classes in the component.
Example:
Using the same example you used, if you go here, you'll see the code for that component.
https://github.com/jquense/react-widgets/blob/f604f9d41652adc29ccd3455bf17997bc001d9ef/packages/react-widgets/src/Multiselect.tsx#L632
(I marked line 632, because that's were the magic happens)
className={cn(className, 'rw-multiselect')}
In there you can see that className is getting a function (since it's between curly brackets it will be evaluated instead of just passing the value).
And if I'm correct, it is using this other library: https://github.com/JedWatson/classnames
which allows you to conditionally set classes.

Is there a way to compile react components to html before build time?

I have a function that takes dom elements and operate on them. It is called pageTransition, and it takes two div elements, and performs a transition animation from the one to the other.
function pageTransition(div1, div2){//do the transition}
for example i can call this function like,
pageTransition (document.body.querySelector("#div1"), document.body.querySelector("#div2"))
That is simple, but let us say I want to pass React class components as my div elements. And that isn't possible because react components are class's not html elements. One quick reminder, this react components in the end will be compiled to div elements with some content during build time. I know I could get around this by doing this
...//the react class
render(
return (
<div id="div1">...</div>//this will allow me to call the above function with the same parameters
)
).
But I was just wondering if there was a magic way to compile this react classes before build time, so rather than giving the id's to the returned div's I was wondering if I could do something like this pageTransition(compile(reactClass), compile(reactClass));
The solution will depend on your intended purpose for pageTransition.
However, there are three potential options you may want to look into:
Statically render a React component into html markup or a string: https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup
Render two div elements in html and use a React portal to manage what is being rendered in the those divs. This could potentially replace what you are doing in pageTransition. https://reactjs.org/docs/portals.html
Use a ref to access the DOM element that is built from the React component: https://reactjs.org/docs/refs-and-the-dom.html
If you explain what pageTransition does it might help me find a solution for you.

Is it good to access DOM in vue js?

I want to know is it OK to access DOM in a Vue js application?
For example, if I want to append an element (div) to body tag is this recommended to use document.getElementById in a Vue js method?
I have no data that can be used to make or remove elements based on data.
I really just want to know is it common to use document to access DOM in Vue js?
Something like this :
methods:{
appendToBody(){
let node = document.createElement("div");
document.getElementById("#body").appendChild(node);
}
}
It depends on what part of the DOM you are referring too.
If you want to change the subtree that is handled by Vue, you shouldn't do that. You should rely on reactive properties, conditional rendering, components. If you need to access an DOM element that is a child of the current component you can use refs.
If you need to change a part of the DOM which is outside of Vue's realm then by all means do it.
In your case is not clear what you want to achieve and is hard to give a clear answer.
You can use DOM functions like document.getElementById in Vue to find elements, but never use DOM functions to change the DOM. Always do modifications within Vue by changing variables and react to it in the template.

jquery with react comparison example

Hi I do understand theoritically that why using jquery with react is not good for DOM. But can anyone give me a practical example with the code of react alone and react with jquery and show how is it not good?
From my understanding, React use a "virtual DOM" to know the current state of the DOM and update only what is necessary. In short, the shadow DOM is just a giant object stored in memory in which React will check what changed to update the DOM. It is possible because in React, you declare in the render method what you want to display.
Jquery conflict with that since you don't use the render to "declare" what you want to display and it might cause side-effect.

Adding content to react elements

I am new to react.js and I have heard that this js library reacts badly to anything that modifies it's component structure.
Is there any specific procedure to add content into react elements using Jquery. For example, if we want to add content into react's div field, can we directly use Jquery append method to insert text to that div or is there any other way to implement things?.
The idea is that you either use a traditional approach, or you ditch jQuery and use react and this means using the react rendering tree, probably build tasks, client-side router/SPA.
You should not modify the DOM generated by react components from outside it since it maintains an internal state and a virtual DOM that would become out of sync. You either use one ecosystem or another; they are two very different approaches to writing a website.
If you want to introduce react on a small part of the website first, I would suggest to gather all your data with jquery and then transmit the data into the react component.
Roughly
// gather data with jquery or whatever
var data_array = gatherData();
ReactDOM.render(<MyCustomComponent data={data_array}/>, $('#my-react-root')[0])
Rendering changes during runtime can be managed the same way. Just gather the data again and change the state of the react component accordingly.
If you don't want to extract the data or the html is to complex, you can use dangerouslySetInnerHTML to just path a plain text html string.
From the docs:
<div dangerouslySetInnerHTML={{__html: getMarkup()}} />
Best wishes
Andreas

Categories

Resources