Monkeytype react clone ⌨️

WHAT TO KNOW - Sep 8 - - Dev Community

<!DOCTYPE html>





MonkeyType React Clone: Building a Typing Test App

<br> body {<br> font-family: sans-serif;<br> margin: 20px;<br> }<br> h1, h2, h3 {<br> margin-top: 30px;<br> }<br> pre {<br> background-color: #f0f0f0;<br> padding: 10px;<br> border-radius: 5px;<br> overflow-x: auto;<br> }<br> .code-block {<br> display: flex;<br> align-items: center;<br> margin-bottom: 10px;<br> }<br> .code-block img {<br> width: 30px;<br> margin-right: 10px;<br> }<br> img {<br> max-width: 100%;<br> height: auto;<br> margin-bottom: 10px;<br> }<br>



MonkeyType React Clone: Building a Typing Test App



MonkeyType is a popular online typing test website that allows users to test their typing speed and accuracy. It's a fun and engaging way to practice typing skills and track progress. In this article, we'll guide you through the process of creating a MonkeyType clone using React, a powerful JavaScript library for building user interfaces.



This project will involve working with:



  • React:
    A JavaScript library for building user interfaces.

  • React Hooks:
    Modern features in React for managing component state and side effects.

  • State Management (Optional):
    Libraries like Redux or Zustand for handling complex application state.

  • CSS:
    Styling the application.

  • APIs (Optional):
    For fetching text passages, storing user data, or integrating with other services.

  1. Project Setup

We'll start by creating a new React project using Create React App. This will provide us with a pre-configured project structure and necessary dependencies.

npx create-react-app monkeytype-clone
cd monkeytype-clone

Once the project is set up, we can run the development server:

npm start

This will open the application in your browser, usually at http://localhost:3000.

  • Components

    We'll break down our MonkeyType clone into several components:

    • App: The main component that renders the other components.
    • TypingArea: Displays the text to be typed and the user's input.
    • Timer: Tracks and displays the elapsed time.
    • Result: Shows the user's typing speed and accuracy after they finish typing.
    • TextPicker: (Optional) Allows the user to select different text passages to type.

  • TypingArea Component

    The TypingArea component is the heart of our application. It handles the following:

    • Displaying the text passage.
    • Taking user input.
    • Highlighting incorrect characters.
    • Calculating words per minute (WPM).

    Here's a basic implementation of the TypingArea component:

  • import React, { useState, useEffect, useRef } from 'react';
    
    function TypingArea() {
      const [text, setText] = useState('');
      const [userInput, setUserInput] = useState('');
      const [startTime, setStartTime] = useState(null);
      const [endTime, setEndTime] = useState(null);
      const [wpm, setWpm] = useState(0);
      const [accuracy, setAccuracy] = useState(0);
    
      const inputRef = useRef(null);
    
      useEffect(() =&gt; {
        fetch('https://api.quotable.io/random')
          .then(response =&gt; response.json())
          .then(data =&gt; setText(data.content));
      }, []);
    
      useEffect(() =&gt; {
        if (startTime &amp;&amp; endTime) {
          const timeTaken = endTime - startTime;
          const wordsTyped = userInput.trim().split(/\s+/).length;
          const calculatedWpm = Math.round((wordsTyped / timeTaken) * 60);
          setWpm(calculatedWpm);
          setAccuracy(calculateAccuracy(text, userInput));
        }
      }, [startTime, endTime, userInput, text]);
    
      const calculateAccuracy = (originalText, typedText) =&gt; {
        let correctCharacters = 0;
        const minLength = Math.min(originalText.length, typedText.length);
        for (let i = 0; i &lt; minLength; i++) {
          if (originalText[i] === typedText[i]) {
            correctCharacters++;
          }
        }
        return Math.round((correctCharacters / originalText.length) * 100);
      };
    
      const handleInputChange = (e) =&gt; {
        setUserInput(e.target.value);
        if (!startTime) {
          setStartTime(Date.now());
        }
      };
    
      const handleKeyDown = (e) =&gt; {
        if (e.key === ' ') {
          setEndTime(Date.now());
        }
      };
    
      return (
      <div>
       <h1>
        Typing Test
       </h1>
       <p>
        {text}
       </p>
       <textarea onchange="{handleInputChange}" onkeydown="{handleKeyDown}" placeholder="Start typing..." ref="{inputRef}" value="{userInput}"></textarea>
       <p>
        WPM: {wpm}
       </p>
       <p>
        Accuracy: {accuracy}%
       </p>
      </div>
      );
    }
    
    export default TypingArea;
    


    In this code:


    • We use state variables to manage the text passage, user input, start/end times, WPM, and accuracy.
    • The useEffect hook fetches a random quote from a quote API to display as the typing text.
    • Another useEffect hook calculates the WPM and accuracy after the user finishes typing.
    • The handleInputChange function updates the userInput state as the user types.
    • The handleKeyDown function records the end time when the user presses the spacebar.
    • We use a textarea element to display the typing area.


    You can customize the API used to fetch the text and implement different ways to display the results.


    1. Timer Component

    The Timer component handles displaying the elapsed time since the user started typing.

    import React, { useState, useEffect } from 'react';
    
    function Timer({ startTime, endTime }) {
      const [elapsedTime, setElapsedTime] = useState(0);
    
      useEffect(() =&gt; {
        let intervalId;
        if (startTime) {
          intervalId = setInterval(() =&gt; {
            setElapsedTime(Date.now() - startTime);
          }, 1000);
        }
        return () =&gt; clearInterval(intervalId);
      }, [startTime]);
    
      const formatTime = (ms) =&gt; {
        const seconds = Math.floor(ms / 1000);
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
      };
    
      return (
      <div>
       {startTime &amp;&amp; endTime ? (
       <p>
        Time: {formatTime(endTime - startTime)}
       </p>
       ) : startTime ? (
       <p>
        Time: {formatTime(elapsedTime)}
       </p>
       ) : (
       <p>
        Time: 00:00
       </p>
       )}
      </div>
      );
    }
    
    export default Timer;
    


    In this code:


    • We use a useEffect hook to update the elapsedTime state every second using setInterval.
    • The formatTime function converts milliseconds to minutes and seconds.
    • We display the time based on whether the user has started and finished typing.

    1. Result Component

    The Result component displays the user's WPM and accuracy after they finish typing.

    import React from 'react';
    
    function Result({ wpm, accuracy }) {
      return (
      <div>
       {wpm &amp;&amp; accuracy &amp;&amp; (
            &lt;&gt;
       <h2>
        Results
       </h2>
       <p>
        WPM: {wpm}
       </p>
       <p>
        Accuracy: {accuracy}%
       </p>
       )}
      </div>
      );
    }
    
    export default Result;
    

    1. App Component

    The App component is the main component that renders all the other components.

    import React from 'react';
    import TypingArea from './TypingArea';
    import Timer from './Timer';
    import Result from './Result';
    
    function App() {
      return (
      <div>
       <typingarea>
       </typingarea>
       <timer>
       </timer>
       <result>
       </result>
      </div>
      );
    }
    
    export default App;
    

    1. Styling

    You can style your MonkeyType clone using CSS. Here's an example of basic styling:

    body {
      font-family: sans-serif;
      margin: 20px;
    }
    
    .typing-area {
      border: 1px solid #ccc;
      padding: 10px;
      border-radius: 5px;
    }
    
    textarea {
      width: 100%;
      height: 150px;
      resize: none;
      padding: 10px;
      font-size: 16px;
    }
    


    Add this CSS to a file named src/App.css and import it into App.js:


    import './App.css';
    


    You can use CSS frameworks like Bootstrap or Tailwind CSS for more advanced styling.


    1. TextPicker Component (Optional)

    To give users more control over the text they type, you can create a TextPicker component that allows them to choose from different text passages. This component could fetch text from a database or use a pre-defined list of texts.

  • State Management (Optional)

    For larger and more complex applications, you might want to use a state management library like Redux or Zustand to manage the application state more efficiently.

  • Deploying Your App

    Once you're satisfied with your MonkeyType clone, you can deploy it to a hosting service like Netlify or Vercel. These services offer easy deployment options for React applications.

    Conclusion

    This article has shown you how to create a MonkeyType clone using React. By building this application, you've gained experience working with:

    • React components and state management.
    • Fetching data from APIs.
    • Handling user input and events.
    • Styling your application with CSS.

    You can extend this project by adding features like:

    • User accounts to save typing history.
    • Leaderboards to compare scores with other users.
    • Custom text input options.
    • Different typing modes like timed or accuracy focused.
    • Game-like elements to make typing more engaging.

    Remember to keep your code clean, well-documented, and maintainable. Happy coding!

    MonkeyType UI Mockup

  • . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    Terabox Video Player