
Reaction time game
9 October, 2023
2
2
0
Contributors
Welcome back to the second day of our Reacteery journey! Today, we've picked a challenging React question that involves diving deep into the world of styled-components. In this blog post, we'll unravel the complexities and demonstrate how to master styled-components in React.
In the world of web development, there's always room for fun and educational projects. Today, we're diving into the creation of a React-based Reaction Time Testing Game using styled-components. This game will challenge your reaction time and provide an interactive way to improve it. Let's explore how it's done!
Introduction
The React Reaction Time Testing Game is a simple yet engaging web game that assesses how quickly you can react to a changing element. The game starts by displaying a red box, and the goal is to click on it as soon as it turns green. Your reaction time, measured in milliseconds (ms), is displayed after each attempt.
Technologies Used
- React: A popular JavaScript library for building user interfaces.
- styled-components: A CSS-in-JS library for styling React components.
Why Styled-Component
Styled-components is a popular library for styling React components. It's widely used in the React ecosystem for several reasons:
- Component-Based Styling: Styled-components allows you to define styles for individual React components by attaching the styles directly to the component definition. This makes it easy to manage styles for specific components and keeps the styling code close to the component code it's associated with.
- Dynamic Styling: Styled-components enable dynamic styling based on props. You can conditionally apply styles based on the state or props of a component, making it versatile for handling different visual states.
- Encapsulation: Each styled component generates a unique class name at runtime. This ensures that styles are scoped to the component, preventing global style pollution or naming conflicts. It's particularly helpful in larger applications with complex styling needs.
- CSS-in-JS: Styled-components embrace the concept of CSS-in-JS, which means writing CSS directly in JavaScript. This approach offers various benefits, such as better code organization, improved tooling support, and the ability to use JavaScript logic to define styles.
- Theming Support: Styled-components provide built-in support for theming, making it easy to create themable components that can adapt to different design systems or themes.
- Server-Side Rendering (SSR) and Critical CSS: Styled-components support server-side rendering out of the box, ensuring that styles are applied correctly on the server and the client. It also allows for the generation of critical CSS for faster initial page loads.
- Auto Vendor Prefixing: Styled-components automatically applies vendor prefixes to CSS properties, reducing the need for manual prefixing and ensuring cross-browser compatibility.
- Integration with Other Libraries: Styled-components can be easily integrated with other popular libraries and tools like React Router, Redux, and CSS preprocessors.
- Great Developer Experience: Many developers find the developer experience with styled-components to be enjoyable. It offers features like syntax highlighting, auto-completion, and easy debugging in modern code editors.
- Active Community: Styled-components have a large and active community, which means there are plenty of resources, tutorials, and community-contributed packages available to help you get the most out of the library.
Overall, styled-components simplifies the process of styling React components, promotes good practices like component encapsulation, and offers a modern and powerful approach to handling styles in React applications. It has become a popular choice for many React developers and continues to evolve with new features and improvements.
Setting Up the Game
To get started, we'll create a React component called ReactionTest
. This component will handle the game's logic and display. Let's break down the key components of the code:
State Management
We use React's useState
hook to manage the game's state. Here are the essential state variables:
COPY
const [startTime, setStartTime] = useState(null);
const [countdownFinished, setCountdownFinished] = useState(false);
const [countdownRunning, setCountdownRunning] = useState(false);
const [message, setMessage] = useState(null);
const timerRef = useRef(null);
startTime
: Records the timestamp when the green box appears, used to calculate reaction time.countdownFinished
: Indicates whether the countdown is finished.countdownRunning
: Indicates whether the countdown is currently running.message
: Stores messages to display to the user.timerRef
: A ref to manage thesetTimeout
used for the game countdown.
Starting the Game
The game begins with a "Start Game" button. When clicked, it initiates the countdown using setTimeout
. The duration of the countdown is random, varying between 1 to 6 seconds, creating an element of surprise.
COPY
const startGame = () => {
setMessage(null);
setCountdownRunning(true);
timerRef.current = setTimeout(() => {
setCountdownRunning(false);
setCountdownFinished(true);
setStartTime(Date.now());
}, Math.random() * 5000 + 1000);
};
Handling Clicks
- If the user clicks on the red box before it turns green, a "You clicked too early!" message is displayed. The game ends immediately.
- If the user clicks on the green box after it turns green, the reaction time in milliseconds is calculated and displayed as "You took <time>ms!".
COPY
const handleClick = () => {
if (countdownFinished && !countdownRunning) {
setMessage(`You took ${Date.now() - startTime}ms!`);
setCountdownFinished(false);
setStartTime(null);
} else {
setMessage('You clicked too early!');
setCountdownFinished(false);
setCountdownRunning(false);
setStartTime(null);
clearTimeout(timerRef.current);
}
};
Styling with styled-components
The game's visual elements, including the red and green boxes and the "Start Game" button, are styled using styled-components
. This library allows us to write CSS-in-JS, making it easy to manage component-specific styles.
COPY
const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 12px;
`
const Button = styled.button`
padding: 10px 20px;
border: none;
border-radius: 4px;
background-color: #333;
color: #fff;
cursor: pointer;
&:hover {
opacity: 0.8;
}
`;
const Box = styled.div`
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
color: white;
border-radius: 5px;
cursor: pointer;
`;
const RedBox = styled(Box)`
background-color: #E74C3C;
`;
const GreenBox = styled(Box)`
background-color: #2ECC71;
`;
Full Code
COPY
import React, { useRef, useState } from 'react';
import styled from 'styled-components';
function ReactionTest() {
const [startTime, setStartTime] = useState(null);
const [countdownFinished, setCountdownFinished] = useState(false);
const [countdownRunning, setCountdownRunning] = useState(false)
const [message, setMessage] = useState(null)
const timerRef = useRef(null);
const startGame = () => {
setMessage(null)
setCountdownRunning(true)
timerRef.current = setTimeout(() => {
setCountdownRunning(false)
setCountdownFinished(true);
setStartTime(Date.now());
}, Math.random() * 5000 + 1000);
};
const handleClick = () => {
setMessage(`You took ${Date.now() - startTime}ms!`)
setCountdownFinished(false);
setStartTime(null);
};
const handleEarlyClick = () => {
setMessage('You clicked too early!')
setCountdownFinished(false);
setCountdownRunning(false)
setStartTime(null);
clearTimeout(timerRef.current)
};
return (
<Wrapper>
{!countdownFinished && !countdownRunning && <Button onClick={startGame}>Start Game</Button>}
{countdownRunning && <RedBox onClick={handleEarlyClick}></RedBox>}
{countdownFinished && <GreenBox onClick={handleClick}></GreenBox>}
<h2>{message}</h2>
</Wrapper>
);
}
export default ReactionTest;
const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 12px;
`
const Button = styled.button`
padding: 10px 20px;
border: none;
border-radius: 4px;
background-color: #333;
color: #fff;
cursor: pointer;
&:hover {
opacity: 0.8;
}
`;
const Box = styled.div`
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
color: white;
border-radius: 5px;
cursor: pointer;
`;
const RedBox = styled(Box)`
background-color: #E74C3C;
`;
const GreenBox = styled(Box)`
background-color: #2ECC71;
`;
Conclusion
The React Reaction Time Testing Game is an enjoyable and educational project that demonstrates how to build interactive games and handle user interactions in React. It challenges your reaction time and provides immediate feedback on your performance.
By combining React with styled-components, we create an engaging and visually appealing user interface. This project is an excellent example of how React can be used for more than just web applications—it can also be a platform for creating fun and interactive web games.
So, are you up for the challenge? Give the game a try and see how fast your reactions are!
What's Next?
The Reacteery journey continues, and there's so much more to explore. Whether you're mastering state management, diving into routing, or conquering advanced topics in React, you're well on your way to becoming a React expert.
Stay tuned for the next exciting installment of Reacteery, where we'll tackle yet another intriguing React question and continue our journey towards React mastery.
Until then, happy coding, and keep Reacteering!
Reacterry Playground - https://www.reacterry.com/portal/challenges/reaction-time-game
Let's chat on Twitter- @Deepakdev1301
#writetowin #showwcase
Stay tuned for more exciting React projects and tutorials!
<Happy coding/>