I have different groups of items. When the user selects a group, the list of items updates and I then want to add a class to all the items in the selected group.
I'm trying to use useEffect to render the items and add a class to them. The problem is that querySelector is finding all items of the previous groupId, not the one being selected. I thought useEffect runs after the render. So shouldn't the items in the selected group render, then run querySelector?
What am I doing wrong? How can I make this work?
export const Component = (props: { groupId: number; }) => {
const { groupId } = props;
useEffect(() => {
let items: any;
items = document.querySelectorAll('.item');
for (let item of items) {
item.classList.add('new-class');
}
}, [groupId]);
return (
<ul>
{items.map((item, index) => (
<li key={index} className='item'>{item.name}</li>
))}
</ul>
);
};
Directly modifying the DOM like that is anti-React. You're straying from a proper data-driven approach and making more work for yourself (and future devs). See Conditionally applying class attributes in React.
You'll either want to conditionally apply your class (without useEffect) or update the styles of the element when the ID value changes (with useEffect).
It's not clear what your business logic is, so I can't be more specific. It appears that you're marking all items as new whenever the group ID changes. Here's a guess at what might work: