I'm converting my jQuery based project to react and run into an issue with refs in a functional component: I have a huge wordlist and each word should be accessed via their own ref so that I can change individual classNames, depending on what the user is typing (I can do it with a huge state object, but the performance suffers).
If I try to access the classlist of a ref, its undefined. Now I'm not sure if classList is generally not available in functional components or if the refs aren't properly initialized:
const wordsRef = useRef([...Array(1000)].map(() => createRef()));
...
const displayWords = words.map((word, index) => (
<React.Fragment key={index}>
<span
ref={wordsRef.current[index]}
>
{word}
</span>{' '}
</React.Fragment>
));
...
useEffect(() => {
wordsRef.current[0].classList.add('highlight');
});
...
return (
<div className={classes.root}>
{displayWords}
</div>
);
Error: Cannot read property 'add' of undefined.
I was only able to find examples with classList, but this is propably not the way to add/remove classes in a functional component?
The code almost works fine, you assigned a reference with .current
property, just change it to:
wordsRef.current[0].current.classList
But you should approach it in other way:
ref={el => (wordsRef.current = [...wordsRef.current, el])
import React, { useRef, useEffect } from 'react';
import ReactDOM from 'react-dom';
const words = ['Many', 'Words'];
const App = () => {
const wordsRef = useRef([]);
const displayWords = words.map((word, i) => (
<React.Fragment key={i}>
<span ref={el => (wordsRef.current = [...wordsRef.current, el])}>
{word}
</span>
</React.Fragment>
));
useEffect(() => {
console.log(wordsRef);
console.log(wordsRef.current[0].classList);
});
return <div>{displayWords}</div>;
};
ReactDOM.render(<App />, document.getElementById('root'));