0

I am trying to get the exact DOM element in the ListItem of List using 'React.useRef(null);' but not able to get it, i am using below code

  useEffect(() => {
   //This is where i am trying to get the exact DOM element
   console.log("listRef", listRef.current);
 }, [searchText]);

Here is my codesandbox link

How to get exact DOM element and what am i missing?

8
  • What do you mean exact DOM element? You are getting the component. Commented Aug 17, 2020 at 13:27
  • @SILENT I need the exact DOM element of the ListItem, after that want to add ` listRef.current && listRef.current.scrollIntoView({behavior: "smooth", block: "nearest"})` to scroll to that one. Do you want me to add the scroll code also to the codesandbox link Commented Aug 17, 2020 at 13:30
  • Check this might help you : stackoverflow.com/questions/54940399/… Commented Aug 17, 2020 at 13:32
  • Your current implementation is referring to the last element. Do you only want to scroll to the last element or any element on the list? Commented Aug 17, 2020 at 13:35
  • @SILENT Yes, exactly that is the issue. I do not want to scroll to last element instead want to scroll to element which contains the first occurrence of searchText entered in searchBar. Commented Aug 17, 2020 at 13:37

2 Answers 2

2

Change your useRef to

const listRef = useMemo(() => messages.map(() => React.createRef<HTMLElement>()), [])

For each list item, set

ref={listRef[id]}

Call the respective item to scroll to using

listRef && listRef[id] && listRef[id].current.scrollIntoView({behavior: "smooth", block: "nearest"});

https://codesandbox.io/s/material-message-search-0x04c?file=/demo.tsx

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks so much, Could you please update my sandbox, since i am using typescript, const listRef = React.useRef({}) is giving error there. Thanks
Typescript type is probably { [key: number]: HTMLElement} . Updated and added codesandbox link
@Thanks for sharing the codesandbox link but unfortunately scroll is yet not working. Is something missed?
@Lara Oops, sorry. Forgot createRef part. Updated
1

Here you go with the code :

Declare the refs array :

const listRef =  React.useMemo(() => messages.map(() => React.createRef()), []);

Update your useEffect code as below:

 useEffect(() => {
    //This is where i am trying to get the exact DOM element
    let index = 1;
    for (let i = 0; i < messages.length; i++) {
      if (
        messages[i].primary.includes(searchText) ||
        messages[i].secondary.includes(searchText)
      ) {
        index = i;
        break;
      }
    }
    
       listRef[index+1].current.scrollIntoView({
        behavior: "smooth",
        block: "nearest"
      });
  }, [searchText]);

Working code example: https://codesandbox.io/s/material-demo-forked-bm4pl?file=/demo.tsx

4 Comments

Thanks so much Harman, i am trying to implement it in my solution, will accept as answer once it works. Thanks again
Why am i getting React Hook "useRef" cannot be called inside a callback at const listRef = Array.from({ length: messages.length }, () => useRef(null));
You need to change this also : <ListItemText ref={listRef[id]} primary={primary} secondary={secondary} /> </ListItem> . Also useRef from react at top where you have imported useEffect
I did that and not getting error there but at this line const listRef = Array.from({ length: messages.length }, () => useRef(null));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.