skip to Main Content

Should I worry about an array full of nulls being stored in a ref?

This is my 1st time posting so I apologize in advance for any mistakes or rules I missed.

I am making a normal autocomplete search bar in React and need to reference
each item that is in the dropdown. I am using useRef to create an array of
the elements that are in the dropdown. My issue is the array of nulls
created when items are eliminated from the dropdown results.

For example if the dropdown first opens with 100 elements in it,
arrayOfElementsRef.current is an array of 100 div elements. When a user
types a character in the input box, the dropdown will change to just
the elements with a value that start with that letter. If there are only 5
elements that match, then arrayOfElementsRef.current is still an array with a length of 100
but the first 5 indexes are the 5 matching values and the remaining 95 indexes are all null.

I know I can add a useEffect that sets arrayOfElementsRef.current.length to 0 every
time the matching values change but:

1. Is it worth it to do that as far as efficiency is concerned?

2. Is it bad practice to have an unlimited-sized array full of nulls?

3. Is there a better way to do this, that you can point me towards?

This is the best way I have found so far but I am worried it might
be better to just leave the array with the null elements.

const **arrayOfElementsRef** = useRef([]);

const [matchingItems, setMatchingItems] = useState([]);

useEffect(() => {
    if (arrayOfElementsRef.current.length !== matchingItems.length) {
        arrayOfElementsRef.current.length = matchingItems.length
    }
}, [matchingItems])

const dropDown = matchingItems.map((item, index) => {
    return (
        <div
            key={item.id}
            ref={el => arrayOfElementsRef.current[index] = el}
        >
            {item.value}
        </div>
    )
})

const handlePrefix = (event) => {
    setMatchingItems(trie.find(event.target.value))
  };

return (
    <div>
        <input type="search" onChange={handlePrefix} />
        <div>{dropDown}</div>
    </div>
)

2

Answers


  1. State (useState) should be enough to achieve this. You don’t need refs (useRef). Consequently, you don’t need the useEffect also.

    Two states should be enough:

    1. A list of all
    2. A list of matching ones (state set by the text input handler, and what items to store in state decided by your prefix logic).

    Note: It is technically possible to use refs for this, but it would be an unnecessarily complicated solution.

    Login or Signup to reply.
  2. First, let’s answer your questions

    1- Yes. Because, it’s either null or an empty string, it’ll still get a place in memory. So, it does effect performance.

    2- Yes. Unless you have a really good reason, there is no logic to have an unlimited-sized array full of nulls.

    I tried to understand your code but still didn’t understand why you have nulls. If trie is your main datasource (which I guess) then instead of find() use regular for loops. Because,

    1. The find() method returns the value of the first element that passes
      a test.
    2. The find() method executes a function for each array element.
    3. The find() method returns undefined if no elements are found.

    So it’s not efficient yet it’will return undefined when there is no match. It is bad practice.

    Use regular for loops on your array of words, then check every word if matches with your keystrokes. If yes, set your state then continue.

    A reminder: regular for loop is way faster than map(), filter(), find().

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search