useEffect is not setting the class in element

180 views Asked by At

A span that has index same as someValue will get a class "someClass" added and rest of the spans will have undefined. useEffect runs when "scrolled" changes and adds class "greyout" to spans that matches the criteria. This runs fine on browser but when I test it it shows class="" for spans that should have class="greyout". It seems like useEffect is not adding the class. Thus, it shows undefined as the element stated inline.

Why is this happening?

const [someState, setSomeState] = useState([]);
const [someValue, setValue] = useState(0);
const [scrolled, setScrolled] = useState(false);

useEffect(() => {
  setScrolled(true);
}, [otherDependency]);

useEffect(() => {
  let children = parentRef.current.children;
  const masterTop = masterDivRef.current.getBoundingClientRect().top;
  Array.from(children).forEach((child) => {
    const childTop = child.getBoundingClientRect().top;
    if (childTop !== masterTop) {
      ele.classList.add("greyout");
    } else {
      child.classList.remove("greyout");
    }
  });
  setScrolled(false);
}, [scrolled]);

return (
  <div>
    <div ref={masterDivRef}>I'm master div</div>
    <div ref={parentRef}>
      {someState.map((val, idx) => {
        return (
          <span className={someValue === idx ? "someClass" : undefined}>
            {val}
          </span>
        );
      })}
    </div>
  </div>
);

1

There are 1 answers

0
peanutz On

The problem was the second useEffect runs twice due to setScrolled in the hook and having scrolled as dependency. Jest doesn't seem to pick up the second render and does not have the end result of "greyout" in the class names. This was fixed by modifying the hook so it only render once when scrolled changes. However, I still don't understand why Jest cannot pick up the second render?