简体   繁体   中英

Alternative for document.querySelector in react js

I've red many articles about using useRef in react js. According to react js documentation , Refs provide a way to access DOM nodes or React elements created in the render method. .
From all of documentation, i understood that, if you want to access a dom element, you have to add the ref like this:
<div ref={myRef} , and after that easy to access it.
I understood that useRef is used when we have access to the html markup.

Question : How to access a css selector ( .class, #id ), when my html is generated by a library, like AntD or something else?
How to access this selector if i can't use document.querySelector according to react documentation? EX:

 document.querySelector('my selector').style.color = 'yellow';

Which is the alternative for the last code snippet in react js?


NOTE : I don't want to change the styles with css, but i need to change it according to some js logic.

You can use querySelector and querySelectorAll in situations where the DOM structure you're accessing is generated outside of React. That's absolutely fine when you have no other choice.

You'd probably use them on the outermost element of your component or the element in which you're having the non-React lirbray do its thing (which you'd get via a ref), rather than on document , so that they're working just within your component's part of the DOM rather than the entire document. Here's an example:

 "use strict"; const { useState, useEffect, useRef } = React; // A stand-in for your non-React library function nonReactLibraryFunction(element, value) { element.innerHTML = `<div> This is content from the non-React lib, value = <span class="value">${value}</span> </div>`; } // A stand-in for your component const Example = ({value}) => { // The ref for the wrapper around the lib's stuff const fooRef = useRef(null); // When `value` changes, have the library do something (this // is just an example) useEffect(() => { // Valid target? if (fooRef.current) { // Yes, let the lib do its thing nonReactLibraryFunction(fooRef.current, value); // Find the element we want to change and change it const color = value % 2 === 0? "blue": "red"; fooRef.current.querySelector(".value").style.color = color; } }, [value]); return ( <div> This is my component, value = {value}. <div ref={fooRef} /> </div> ); }; // A wrapper app that just counts upward const App = () => { const [value, setValue] = useState(0); useEffect(() => { setTimeout(() => setValue(v => v + 1), 800); }, [value]); return <Example value={value} />; }; ReactDOM.render(<App />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.development.js"></script>

If you use external libraries that generate their own markup. Nothing bad to use element.querySelector

You can do something like this:

React.useEffect(() => {
   const element = document.querySelector(selector);
}, []);

But if you use a library from React's ecosystem like Antd or material-ui, they probably have an API with refs. It can be called like innerRef , nestedRef or just ref

In addition to previous anwsers: if this generated html is generated inside your component you can use querySelector on useRef.current to search for element only inside component;)

const Component = () => {
  const componentRef = useRef(null);

  useEffect(() => {
    const elFromLibraryComponent = componentRef.current.querySelector('my selector');

    if (elFromLibraryComponent) {
       ...do something...
    }
  }, [])

  return (
    <div ref={componentRef}>
      <ComponentFromLibrary />
    </div>
  )
}

There are even libraries that allows to pass ref as prop to components so it is also usefull

If you are using multiple external resources to generate markup. Try this:

useEffect(() => {
const element = window.parent.document.querySelector(selector);
},[]);

We can also manipulate HTML Dom element by tags,id,class with the help of document.getElementsByTag('TagName').Document.getElementById('IdName'),Document.getElementsByClass('ClassName').

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM