Users should be able to:
- Select and submit a number rating
- See the "Thank you" card state after submitting a rating
- See hover and focus states for all interactive elements on the page
Mobile design
Active state
"Thank You" card state
- React.js
- React Hooks (
useState
,useEffect
, and customuseMediaQuery
) - CSS Modules
- CSS Custom Properties
- CUBE CSS methodology
- CSS Flexbox & Grid
- Mobile-first workflow
- Netlify for deployment
This project was a full deep dive into structuring a React component-based application while implementing best practices for state management, hooks, and styling methodologies. Here are my few key takeaways:
One of the first things I noticed was that clicking the back button didn’t return to the rating card. My instinct was to navigate back, so I implemented a solution using the popstate event to handle browser history changes.
// Listen for browser back button
useEffect(() => {
const handlePopState = () => {
setIsSubmitted(false); // Reset submission state
setSelectedRating(null); // Reset rating selection
};
window.addEventListener("popstate", handlePopState);
return () => window.removeEventListener("popstate", handlePopState);
}, []);
This ensures that when users click the back button, the app resets correctly instead of getting stuck in a submitted state.
For the desktop version, I needed to adjust the card size dynamically. I implemented a custom React Hook (useMediaQuery
) to check screen width and conditionally apply different class names for styling.
function useMediaQuery(query) {
// Tracks whether the media query matches or not
const [matches, setMatches] = useState(() => {
return window.matchMedia(query).matches; // Initialize state based on current match status
});
useEffect(() => {
const mediaQueryList = window.matchMedia(query); // Create a media query list object
const updateMatch = (event) => setMatches(event.matches); // Update state when the media query match status changes
mediaQueryList.addEventListener("change", updateMatch); // Attach the event listener
return () => {
mediaQueryList.removeEventListener("change", updateMatch); // Cleanup function to remove the event listener when the component unmounts
};
}, [query]); // Runs only when the query changes
return matches; // Return the boolean value indicating if the query matches
}
This allowed me to swap out class names dynamically, especially since I use CSS utility classes, ensuring a smooth transition between mobile and desktop layouts.
I focused on keeping my React components modular and reusable, breaking them down into:
Card.jsx
– Main rating cardRatingButton.jsx
– Individual rating buttonsRatingGroup.jsx
– Group of rating buttonsSubmitButton.jsx
– Submission buttonThankYouCard.jsx
– Thank you message
This structure helped separate concerns, making it easier to manage state and styles independently.
Moving forward, I want to:
- Explore React Context API for managing state globally.
- Improve handling of accessibility (ARIA labels, focus states, screen reader support).
- Continue refining my CSS architecture by balancing utilities with component-scoped styles.
I struggled with props
management during this project, so I want to hone my skills more in creating React apps and deep dive into other useful hooks that are common in the industry.
To run this project locally, follow these steps:
- Clone the repository
git clone https://github.com/vivian-mca/interactive-rating-component.git
cd your-repo-name
- Install dependencies
npm install
- Run the development server
npm run dev
This will start the project on http://localhost:5173/ (or another available port if 5173 is in use).
- Build for production If you want to create an optimized production build:
npm run build
- Preview the production build
npm run preview
This will serve the built project locally for testing.
This project is deployed using Netlify. If you want to deploy your own version:
- Push your code to GitHub (or any Git provider).
- Connect the repository to Netlify.
- Set the build command:
npm run build
- Set the publish directory:
dist
- Deploy and share your live project!
- React Docs - They really have great documentation on everything React.
- CSS Logical Properties and Values - This is a good resource for learning about CSS Logical Properties and Values.
- CUBE CSS documentation - From the docs: "CUBE CSS is a CSS methodology that’s orientated towards simplicity, pragmatism and consistency. It’s designed to work with the medium that you’re working in—often the browser—rather than against it."
- Every Layout - Extremely helpful resource for simplifying CSS layouts.
- Figma - Really helpful for extracting information about measurements
- Modern CSS Reset
- Perfect Pixel - Awesome Chrome extension that helps you to match the pixels of the provided design.
- Responsively App - This DevTool helps in responsive web development. It allows you to see mirrored user-interactions across all devices. I find it helpful in finding breaking points and making sure my app is responsive.
- Frontend Mentor - @vivian-mca