react-typist icon indicating copy to clipboard operation
react-typist copied to clipboard

not working correctly for dynamically rendered content wrapped in {}

Open laurencefass opened this issue 4 years ago • 6 comments

Hi this is a great module many thanks for creating it.

Im trying to create a monitor effect but having a problem with dynamically rendered content i.e. rendered content wrapped in {...}

Sandbox here: https://codesandbox.io/s/react-typist-demo-5p58v?file=/src/App.js

Ive put wrapped an unwrapped content so you can see the effect of applying <Typist> around dynamic content.

I dont know if this is outside the scope of design/use but any help or advice much appreciated.

laurencefass avatar Jun 25 '20 12:06 laurencefass

same for me

cxspxr avatar Aug 09 '20 20:08 cxspxr

Okay, got a solution, planning to make documentation PR at least

If you go dynamically you should try to add adding key prop to Typist so that it will be forced to re-render every time on key prop change.

so .e.g.

import React, { useState } from "react";
import Typist from "react-typist";

const DynamicTypist = () => {
  const texts = ["first text", "second text", "third text"];
  const [currentTextCounter, setCurrentTextCounter] = useState(0);



  return <div onClick={() => if (currentTextCounter < texts.length - 1) { setCurrentTextCounter(currentTextCounter + 1)} }>
    <Typist key={currentTextCounter}>
      {texts[currentTextCounter]}
    </Typist>
  </div>
}

cxspxr avatar Aug 10 '20 09:08 cxspxr

makes perfect sense and i think the correct "React way" of using this. Thanks.

laurencefass avatar Aug 10 '20 10:08 laurencefass

Actually not quite :) I think that @jstejada or someone should fix shouldComponentUpdate of Typist component so that it will re-render or children prop change. Right now it ignores any changes of props. https://github.com/jstejada/react-typist/blob/d067d1a0a357ac221ddb83efe4e0d9719a39c672/src/Typist.jsx#L68

Right now my solution is somewhat hacky, but still works fine at least. No problems with that, no performance issues with basic dynamic content whatsoever, but the react-way would be to fix shouldComponentUpdate method inside Typist, but as I also see the latest release was a year ago, I am not sure that this repo is still maintained.

But feel free to open/close, because it can be considered either as somewhat solved with my proposal and not solved in a sense of react-way.

cxspxr avatar Aug 10 '20 10:08 cxspxr

Your workaround make sense if you use typist int he same component where the text is rendered, but it doesn't solve the other major use case, i.e. text rendered in child components unfortunately.

th3n3rd avatar May 29 '21 14:05 th3n3rd

I wrote a component that might work for this, or at least similar issues. It's a little hacky but hey. I needed it to be like this because I'm not cycling through a list of strings on user clicks, I'm trying to display a value from an api query which updates sometimes from polling. Hope this helps people checking out this thread. Thank you to the creator/contributors for the super cool package.

import React, { ReactNode, useEffect, useState } from 'react'
import Typist from 'react-typist'

const DynamicTypist = ({ children }: { children: ReactNode }) => {
  const [content, setContent] = useState(children)
  const [needsUpdate, setNeedsUpdate] = useState(false)

  useEffect(() => {
    if (JSON.stringify(children) !== JSON.stringify(content)) {
      setNeedsUpdate(true)
    }
  }, [children])

  useEffect(() => {
    setContent(children)
    setNeedsUpdate(false)
  }, [needsUpdate])

  return needsUpdate ? <></> : <Typist>{content as any}</Typist>
}

export default DynamicTypist

ThomasFoydel avatar Jan 10 '23 00:01 ThomasFoydel