skip to Main Content

I want to make a typing efect, but the 2nd letter is not added.

For example:

I want to write "Hello World" and it displays "Hllo World".

my code:

export default function Error({ errorMsg }) {
    const [errorString, setErrorString] = useState("");
    let i = 0;

    useEffect(() => {
        writeError();
    }, []);

    function writeError() {
        let timer = Math.floor(Math.random() * (100 - 25 + 1)) + 25;

        setTimeout(() => {
            if (i < errorMsg.length) {
                setErrorString(errorString => ([
                    ...errorString,
                    errorMsg.charAt(i)
                ]));
                i++;
                return writeError();
            }
        }, timer);
    }

    return (
        <div>
            <div id="wrp">
                <div>{errorString}</div>
            </div>
        </div>
    );
}

Why does the error only occur with the 2nd character, no matter how long the string is?

Edit

Thanks for the solutions, but the solution of @DecPK is the best in my opinion

fixed code:

export default function Error({ errorMsg }) {
    const [errorString, setErrorString] = useState("");
    let i = 0;

    useEffect(() => {
        writeError();
    }, []);

    function writeError() {
        let timer = Math.floor(Math.random() * (100 - 25 + 1)) + 25;

        setTimeout(() => {
            if (i < errorMsg.length) {
                setErrorString(errorString => ([
                    ...errorString,
                    errorMsg.charAt(i++) // <-- Answer from @DecPK
                ]));
                return writeError();
            }
        }, timer);
    }

    return (
        <div>
            <div id="wrp">
                <div>{errorString}</div>
            </div>
        </div>
    );
}

4

Answers


  1. Chosen as BEST ANSWER

    Answer from @DecPK

    This is a React functional component that renders an error message with a typing effect. Here is a commented version of the code:

    // Import React and the useState and useEffect hooks
    import React, { useState, useEffect } from "react";
    
    // Define the Error component as the default export of this module
    export default function Error({ errorMsg }) {
    
      // Define a state variable "errorString" and a function "setErrorString" to update it
      const [errorString, setErrorString] = useState("");
    
      // Define a variable "i" to keep track of the index of the current character being typed
      let i = 0;
    
      // Use the useEffect hook to trigger the writeError function once, when the component is first mounted
      useEffect(() => {
        writeError();
      }, []);
    
      // Define the writeError function to update the errorString state variable with a new character every few milliseconds
      function writeError() {
    
        // Generate a random timeout between 25ms and 100ms
        let timer = Math.floor(Math.random() * (100 - 25 + 1)) + 25;
    
        // Use the setTimeout function to wait for the random timeout before updating the errorString state variable with the next character
        setTimeout(() => {
    
          // Check if there are more characters to type
          if (i < errorMsg.length) {
    
            // Update the errorString state variable by appending the next character to it
            setErrorString(errorString => ([
              ...errorString,
              errorMsg.charAt(i++) // Get the character at the current index and increment i
            ]));
    
            // Call the writeError function again to type the next character after another random timeout
            return writeError();
          }
        }, timer);
      }
    
      // Render the component by returning a div with an id "wrp" and another div that displays the errorString state variable
      return (
        <div>
          <div id="wrp">
            <div>{errorString}</div>
          </div>
        </div>
      );
    }
    

    In summary, this component uses the useState and useEffect hooks to update the error message with a typing effect, using the setTimeout function to wait for a random timeout between each character.


  2. The issue with updating a string in useState in React is that you cannot update a string directly like you can with other types such as numbers or booleans. Strings are immutable, meaning that once they are created, they cannot be modified. Therefore, any updates to a string variable create a new string and assign it to the variable.

    To update a string in useState, you can use the set function provided by the useState hook, passing in the new string value as an argument. For example:

    const [myString, setMyString] = useState('Hello world');
    
    // Updating the string value using set function
    setMyString('Hello React');
    

    In the example above, the setMyString function updates the value of the myString state variable to ‘Hello React’. When using setMyString to update the string value, you should make sure to always pass a new string as the argument, even if it has the same value as the previous string. This is because React will only re-render the component if the state value reference changes.

    Here’s an example of updating a string value using setMyString in response to a button click:

    function MyComponent() {
      const [myString, setMyString] = useState('Hello world');
    
      function handleClick() {
        setMyString('Hello React');
      }
    
      return (
        <div>
          <p>{myString}</p>
          <button onClick={handleClick}>Update string</button>
        </div>
      );
    }
    

    In this example, clicking the "Update string" button will update the myString state variable to ‘Hello React’ and cause the component to re-render with the new string value.

    Login or Signup to reply.
  3. My Answer:

    import { useState, useEffect } from "react";
    
    export default function Error({ errorMsg }) {
        const [errorString, setErrorString] = useState("");
        let i = 0;
    
    
        useEffect(() => {
            const interval = setInterval(() => writeError(), 200);
            return () => clearInterval(interval);
        }, []);
    
        function writeError() {
            setErrorString(errorMsg.substring(0, i));
            i++;
        }
    
        return (
            <div>
                <div id="wrp">
                    <div>{errorString}</div>
                </div>
            </div>
        );
    }
    

    Please try to execute this.

    Login or Signup to reply.
  4. Please consider the solution below. This component is responsible for managing it’s cursor state. It then calculates the text to show in render using the errorMsg prop. This is the React way.
    Sandbox demo available

    export function Error({ errorMsg }) {
      const [cursor, setCursor] = React.useState(0);
      const randomDelay = Math.floor(Math.random() * (100 - 25 + 1)) + 25;
    
      React.useEffect(() => {
        if (!(cursor <= errorMsg.length)) return;
        const id = setTimeout(() => setCursor(cursor + 1), randomDelay);
        return () => clearTimeout(id);
      }, [cursor, errorMsg.length, randomDelay]);
    
      return (
        <div>
          <div id="wrp">
            <div>{errorMsg.substr(0, cursor)}</div>
          </div>
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search