0

container is complaining because HTMLDivElement | null is not assignable to Element type

export const Loader: React.FC = () => {
  const element = useRef<HTMLDivElement>(null);  
  useLayoutEffect(() => {
    lottie.loadAnimation({
      animationData,
      container: element.current,
      loop: true
    });
  });

  return (
    <Wrapper>
      <div ref={element}></div>
    </Wrapper>
  );
};
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
khierl
  • 605
  • 1
  • 6
  • 16
  • Try `null as any` – oemera Nov 19 '19 at 06:14
  • @oemera the container is typed to only accepts Element type, ```container: Element``` – khierl Nov 19 '19 at 06:22
  • Can you show the exact error message? – oemera Nov 19 '19 at 06:41
  • @oemera `Type 'HTMLDivElement | null' is not assignable to type 'Element'. Type 'null' is not assignable to type 'Element'.` on the lottie package: index.d.ts(53, 5): The expected type comes from property 'container' which is declared here on type 'AnimationConfigWithPath | AnimationConfigWithData' – khierl Nov 19 '19 at 07:02
  • @oemera as far as I know the useRef should already have value on it upon calling inside the useLayoutEffect – khierl Nov 19 '19 at 07:04
  • I don't think thats true. Thats true for `useEffect`. But you still initialized your `useRef` with `null`, so the type is `HTMLDivElement | null` even if it can't ever be null in the `useEffect`. You have to check manually, if it is null. See my answer. – oemera Nov 19 '19 at 07:28

1 Answers1

5

You have to make sure element.current has a value before you call loadAnimation. Try this:

export const Loader: React.FC = () => {
  const element = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if(element.current) // add this
       lottie.loadAnimation({
         animationData,
         container: element.current,
         loop: true
       });
  }, [element]); // add this, it triggers this effect everytime element changes

  return (
    <Wrapper>
      <div ref={element}></div>
    </Wrapper>
  );
};

OR

container: element.current as HTMLDivElement,    

OR

container: element.current!,    

The first option is the cleanest, since it's less error prone.

oemera
  • 3,223
  • 1
  • 19
  • 33
  • 1
    Thanks for this! this is the correct answer. Tho still need to put `null` inside the `useRef` also I omitted the dependency because warning says: React Hook useLayoutEffect has an unnecessary dependency: 'element.current'. Either exclude it or remove the dependency array. Mutable values like 'element.current' aren't valid dependencies because mutating them doesn't re-render the component – khierl Nov 19 '19 at 08:41
  • 1
    `element` instead of `element.current` on the hook dependency works – khierl Nov 19 '19 at 08:50