camwiegert / typical

Animated typing in ~400 bytes 🐡 of JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: How can we break/destroy an infinite loop of typical

Jordan-T opened this issue · comments

Hello,

I tried to break a loop but I found no solution.
Do you have a solution for this?

Thank you

@Jordan-T The way looping works now is: if you pass a function, it will be called with the same arguments and awaited. If you pass type as an argument to itself, it will be called recursively. You could wrap type and call it conditionally:

const maybeLoop = (..args) => shouldContinue ? type(...args) : null;

type(target, 1000, 'Hello', 1000, 'Hello world!', maybeLoop);

If shouldContinue is falsy, it will stop the loop. Otherwise it will continue. And shouldContinue could be set dynamically or be a function call. Does that cover your use case?

@camwiegert It not really solve my issue. The issue is on React, the component rerender and it recall type with the same target but previous type was not destroyed. So each type instance change the text at the same time.

I need a destroy or a break before the text change. Just keep the last instance of type.

Could you just check if the Promise that type returns has resolved before calling it again?

Also, if you're not aware, there is a React component wrapper of typical: https://github.com/catalinmiron/react-typical

I already use this plugin, but at the rerender not working.
I clone this component for local testing but I can't remove a typical previously initialized.
The only solution I found is after each waiting, check if shouldContinue is true

Thanks for bringing this up. Sounds like you've got something workable now, if not ideal. This is something I'll consider for a future release.

Thanks for your time and your awesome tiny library 🙌

For anyone arriving here from google here's how I solved it with React

I basically add a check function before each argument that will throw and stop the animation when the component is unmounted.

export function Typical({ args, ...props }) {
  const ref = useRef();
  const alive = useRef(true);
  useEffect(() => {
    async function check() {
      if (!alive.current) {
        throw new Error();
      }
    }
    type(
      ref.current!,
      ...args.flatMap((arg) => [check, arg]),
      type
    ).catch(() => {});
    return () => {
      alive.current = false;
    };
  }, []);
  return <span {...props} ref={ref} />;
}