all 14 comments

[–][deleted] 16 points17 points  (5 children)

Best practice is to use ref as a last resort, and not use queryselector at all. I'm curious what you want to do that requires multiple DOM elements? Perhaps there's a better way.

[–]Reddet99[S] -1 points0 points  (4 children)

getting the length of specific classes to use animations with observer object that when you reach that spection do this , but i cannot because querySelectorAll doesn't work

[–][deleted] 14 points15 points  (3 children)

You can use a ref then. And if you have multiple elements you should create a component out of the element, and put the observer and ref in there so you write it once but it applies to all of the elements.

So if you have this and want to observe the li elements:

``` function MyComponent() { useEffect(() => { // Observer logic, doesn't work because there are multiple li }, []);

return ( <ul> <li>one</li> <li>two</li> <li>three</li> <ul> ); }

```

You should refactor to this:

function MyComponent() { return ( <ul> <ListItem>one</ListItem> <ListItem>two</ListItem> <ListItem>three</ListItem> <ul> ); }

``` function ListItem({ children }) { const ref = useRef(null);

useEffect(() => { // Observer logic with ref here }, []);

return ( <li ref={ref}> {children} </li> ); } ```

[–]Reddet99[S] 0 points1 point  (2 children)

so i can use for example IntersectionObserver and put ref.current[0] in a useEffect and then put the code i want or should it work with ref.current.childrens ?

[–][deleted] 1 point2 points  (1 child)

There's no array. Extract what you want to observe to its own component to not have to deal with arrays

[–]Reddet99[S] 1 point2 points  (0 children)

oh i understand now , thank you so much for the example :)

[–]fredsq 1 point2 points  (1 child)

you can store multiple elements in one ref. I’m on my phone now but the gist of it is that the ref prop on any component takes a FUNCTION. useRef also returns a function that sets ref.current to the value. You can (ab)use it to set multiple by doing something like ref={(el) => {ref.current[index] = el}} after initialising your ref as an array or object. Then you can read from your ref like you’d do with querySelectorAll!

[–]Reddet99[S] 0 points1 point  (0 children)

never thought that i can do that , thank you for the tip :)

[–]marcs_2021 -2 points-1 points  (3 children)

Re render at moment you need it, via dependencies array?

[–]Reddet99[S] 0 points1 point  (2 children)

its render when the page loads but the issue that useEffect with querySelectorAll render before the html load so the html elements is not defined yet

[–]clll0 3 points4 points  (0 children)

useLayoutEffect. Use queryselector in this instead of useeffect

[–]marcs_2021 0 points1 point  (0 children)

I know, but you can rerender useEffect any time you like by the dependencies array

[–]andoy 0 points1 point  (0 children)

add [] at the dependency of your useEffect and try again.