【问题标题】:Is there a better way to write this React typing animation?有没有更好的方法来编写这个 React 打字动画?
【发布时间】:2021-07-18 22:15:43
【问题描述】:

我使用 react 功能组件以及 useEffect 和 useState 挂钩创建了一个打字效果。代码完全按照我想要的方式工作,但我想知道是否有更短、更简洁的解决方案来使用功能组件实现相同的效果?每个单词都必须一个接一个地输入,并且每个单词都必须有自己的 span 标签用于布局目的。我是 React 的新手,我真的很难做到这一点,所以如果有人有更好的解决方案,我将不胜感激。谢谢。

codeandbox 链接:React Typing Animation

App.js:

import "./styles.css";
import { useState, useEffect } from "react";

export default function App() {

  const [text0, setText0] = useState("");
  const [text1, setText1] = useState("");
  const [text2, setText2] = useState("");
  const [text3, setText3] = useState("");
  const [text4, setText4] = useState("");
  const [text5, setText5] = useState("");
  const [text6, setText6] = useState("");
  const [text7, setText7] = useState("");
  const [text8, setText8] = useState("");
  const [text9, setText9] = useState("");
  const [text10, setText10] = useState("");

  const [index, setIndex] = useState(0);
  const [subIndex, setSubIndex] = useState(0);
  const [cursor1Class, setcursor1Class] = useState("cursor");
  const [cursor2Class, setcursor2Class] = useState("cursorHidden");
  const [cursor3Class, setcursor3Class] = useState("cursorHidden");
  const words = ["Horse", " Chicken", " Dog", " Cat", "Toad", " Lion", " Bird", " Elephant",      
  "Insect", " Snake", " Frog"];

  useEffect(() => {
    if (index === words.length) return;

    if (subIndex >= words[index].length + 1) {
        setSubIndex(0);
        setIndex((prev) => prev + 1);  

       if (index === 3) {
          setcursor1Class((prev) => prev + " cursorHidden");
          setcursor2Class("cursor");
       }

       if (index === 7) {
          setcursor2Class((prev) => prev + " cursorHidden");
          setcursor3Class("cursor");
       }

       return;
    }

    if (subIndex <= words[index].length + 1) {
       setTimeout(() => {
        setSubIndex((prev) => prev + 1);
        if (index === 0) {
          setText0(words[index].substring(0, subIndex));
        } else if (index === 1) {
          setText1(words[index].substring(0, subIndex));
        } else if (index === 2) {
          setText2(words[index].substring(0, subIndex));
        } else if (index === 3) {
          setText3(words[index].substring(0, subIndex));
        } else if (index === 4) {
          setText4(words[index].substring(0, subIndex));
        } else if (index === 5) {
          setText5(words[index].substring(0, subIndex));
        } else if (index === 6) {
          setText6(words[index].substring(0, subIndex));
        } else if (index === 7) {
          setText7(words[index].substring(0, subIndex));
        } else if (index === 8) {
          setText8(words[index].substring(0, subIndex));
        } else if (index === 9) {
          setText9(words[index].substring(0, subIndex));
        } else if (index === 10) {
          setText10(words[index].substring(0, subIndex));
        }
      }, 150);
    }
  }, [subIndex]);

  return (
    <div>
      <div>
        <span className="colorBlue">{text0}</span>
        <span className="colorRed">{text1}</span>
        <span className="colorPurple">{text2}</span>
        <span className="colorGreen">{text3}</span>
        <span className={cursor1Class}>|</span>
      </div>

      <div>
        <span className="colorBlue">{text4}</span>
        <span className="colorRed">{text5}</span>
        <span className="colorPurple">{text6}</span>
        <span className="colorGreen">{text7}</span>
        <span className={cursor2Class}>|</span>
      </div>

      <div>
        <span className="colorBlue">{text8}</span>
        <span className="colorRed">{text9}</span>
        <span className="colorPurple">{text10}</span>
        <span className={cursor3Class}>|</span>
      </div>
    </div>
  );
}

styles.css:

 body {
  font-size: 25px;
  font-weight: bold;
 }

.colorRed {
  color: #e41919;
}

.colorBlue {
  color: #213296;
 }

 .colorPurple {
  color: #810871;
 }

.colorGreen {
  color: #09b417;
}

.cursorHidden {
 display: none;
}

.cursor {
 color: black;
 animation: 1s blink step-end infinite;
 }

@keyframes blink {
 from,
 to {
  color: transparent;
 }
 50% {
  color: black;
 }
}

index.js:

import { StrictMode } from "react";
import ReactDOM from "react-dom";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(<StrictMode><App /></StrictMode>, rootElement);

【问题讨论】:

    标签: reactjs use-effect use-state


    【解决方案1】:

    这样我强烈建议使用 useReducer 钩子和 switch case,这将有助于以更好的编码体验达到相同的结果

    【讨论】:

    • 非常感谢 vinodel.max 的建议 - 听起来不错 - 我会考虑使用 useReducer
    猜你喜欢
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 2023-03-17
    • 2021-09-20
    相关资源
    最近更新 更多