Home > Software design >  React typing animation restarts every time setState is called
React typing animation restarts every time setState is called

Time:05-30

I have my portfolio set up with react-typing-animation for the headers/titles of each of the pages. On the pages where state is used for something and the typing animation has not finished typing out the title and setState is called, the typing animation restarts.

For example, on my homepage I am going to add a nice background scroll effect, and I have state setup to track the scroll on the Y axis, so if the homepage loads and you scroll down, the title constantly resets and starts typing all over as you scroll. It also does this on the page with my TicTacToe game, if you start playing the game before the animation completes, it restarts because your spot on the TicTacToe board is stored in state.

example image

I am assuming I might need to do something with state and the typing animation. Maybe store the animation in state somehow and pass it to each page you go to? I am not sure.

here is a snippet of the homepage:

import React, { useState, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Box from "@material-ui/core/Box";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";

import GitHubCard from "../apps/githubCard/index";
import Bio from "../apps/bio/bio";
import AnimatedTypingComponent from "../anim/headerType";

import styles from "./homepage.module.scss";

const useStyles = makeStyles((theme) => ({
    root: {
        flexGrow: 1,
    },
    columns: {
        padding: theme.spacing(2),
        textAlign: "center",
        width: "100%",
    },
}));

// This will be the landing page for our application.
export default function HomePage() {
    const classes = useStyles();
    const [offsetY, setOffsetY] = useState(0);
    const handleScroll = () => {
        setOffsetY(window.pageYOffset);
    };

    useEffect(() => {
        window.addEventListener("scroll", handleScroll);
        return () => {
        window.removeEventListener("scroll", handleScroll);
        };
    }, []);

return (
    <div className={styles.homepage}>
        <div>
            <AnimatedTypingComponent title={"Hello I'm Russell Livermore"} title2={"Welcome to my portfolio"} />
        </div>
        

Here is the code for the typing animation

 import React from "react";
 import Typing from "react-typing-animation";

 import styles from "./header.module.scss";

export default function AnimatedTypingComponent(props) {
    const { title, title2 } = props;

    return (
        <div className={styles.header}>
            <Typing className={styles.typing}>
                <div id={styles.header}>{title}</div>

                <Typing.Delay ms={1000} />
                <div id={styles.wel}>{title2}</div>
            </Typing>
        </div>
    );
}

CodePudding user response:

You can use React.memo to Memorize your component to prevent re-render

const MemoAnimatedTypingComponent  = React.memo(({...props}) => <AnimatedTypingComponent  {...props}/>);

In your code

import React, { useState, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Box from "@material-ui/core/Box";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";

import GitHubCard from "../apps/githubCard/index";
import Bio from "../apps/bio/bio";
import AnimatedTypingComponent from "../anim/headerType";

import styles from "./homepage.module.scss";

const MemoAnimatedTypingComponent = React.memo(({...props}) => (
  <AnimatedTypingComponent {...props}/>
));

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  columns: {
    padding: theme.spacing(2),
    textAlign: "center",
    width: "100%",
  },
}));

// This will be the landing page for our application.
export default function HomePage() {
  const classes = useStyles();
  const [offsetY, setOffsetY] = useState(0);
  const handleScroll = () => {
    setOffsetY(window.pageYOffset);
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <div className={styles.homepage}>
      <div>
        <MemoAnimatedTypingComponent
          title={"Hello I'm Russell Livermore"}
          title2={"Welcome to my portfolio"}
        />
      </div>
    </div>
  );
}

A simple Example

import React, { useEffect, useState } from "react";

const MemoComp = React.memo(({ ...props }) => <Test {...props} />);
function ClassSearch() {
  const [state, setState] = useState(1);
  return (
    <div>
      <button onClick={() => setState(state   1)}>Increase</button> <br />
      <MemoComp data="memorized" /> <br />
      <Test data="original" /> <br />
    </div>
  );
}

export default ClassSearch;

const Test = ({ data }) => {
  const date = new Date().getTime();
  return (
    <>
      Test {date} {data}
    </>
  );
};

  • Related