tameemsafi / typewriterjs

A simple yet powerful native javascript plugin for a cool typewriter effect.
https://www.npmjs.com/package/typewriter-effect
MIT License
2.46k stars 220 forks source link

Why does not typeString() parameter update after rerender? #154

Open IxxyDev opened 2 years ago

IxxyDev commented 2 years ago

I have my string inside state in React. State changes every 10 seconds (so re-render happens too). But when state is changed and component re-rendered, new line of text does not appear.

const [currentTitle, setCurrentTitle] = useState(''); // changes every 10 seconds

return (
  .....
  <Typewriter
        onInit={tw => tw
            .changeDelay(50)
        .typeString(currentTitle)
        .pauseFor(5000)
        .deleteAll(50)
                 .start()
    }
    options={{ cursor: '_', devMode: true }}
  />

Any suggestions how to handle this?

NanobyteRuata commented 1 year ago

My (kinda) workaround for temporary fix

const renderTypewriter = (text) => (<Typewriter
        onInit={tw => tw
            .changeDelay(50)
        .typeString(currentTitle)
        .pauseFor(5000)
        .deleteAll(50)
                 .start()
    }
    options={{ cursor: '_', devMode: true }}
  />);

const [currentTitle, setCurrentTitle] = useState(''); // changes every 10 seconds
const [theTypewriter, setTheTypewriter] = useState(renderTheTypewriter(currentTitle));

useEffect(() => {
        setTheTypewriter(<></>);
        setTimeout(() => setTheTypewriter(currentTitle))
}, [ currentTitle ]);

return (
  .....
  { theTypewriter }
  .....
);
iUnstable0 commented 1 year ago

My (kinda) workaround for temporary fix

const renderTypewriter = (text) => (<Typewriter
        onInit={tw => tw
          .changeDelay(50)
      .typeString(currentTitle)
      .pauseFor(5000)
      .deleteAll(50)
                 .start()
  }
  options={{ cursor: '_', devMode: true }}
  />);

const [currentTitle, setCurrentTitle] = useState(''); // changes every 10 seconds
const [theTypewriter, setTheTypewriter] = useState(renderTheTypewriter(currentTitle));

useEffect(() => {
        setTheTypewriter(<></>);
        setTimeout(() => setTheTypewriter(currentTitle))
}, [ currentTitle ]);

return (
  .....
  { theTypewriter }
  .....
);

it should be

setTimeout(() => setTheTypewriter(renderTypewriter()))

also not sure why you kept the text args in the renderTypeWriter func when you're not using it. for me, I change the text like this

const getRandomGreetings = () => {
    ...
}

const [greeting, setGreeting] = useState(getRandomGreetings());

const renderTypewriter = () => {
    return (
        <Typewriter
            options={{
                autoStart: true,
                // loop: true,
                // devMode: true,
            }}
            onInit={(typewriter) => {
                typewriter
                    .typeString(greeting)
                    .pauseFor(5000)
                    .deleteAll()
                    .start()
                    .callFunction(() => {
                        setGreeting(getRandomGreetings());
                    });
            }}
        />
    );
};

const [typewriter, setTypewriter] = useState(renderTypewriter());

useEffect(() => {
    setTypewriter(<></>);
    setTimeout(() => setTypewriter(renderTypewriter()));
}, [greeting]);

return (
  .....
  {typewriter}
  .....
);
NanobyteRuata commented 1 year ago

yeah, thanks. i forgot so much to change when i copied from the code i was using.

iUnstable0 commented 1 year ago

yeah, thanks. i forgot so much to change when i copied from the code i was using.

haha xD even though that code works, it glitches over time (kinda like multiple typewriter running in the background) it's weird