{"id":25169721,"url":"https://github.com/sofiane-abou-abderrahim/react-the-almost-final-countdown","last_synced_at":"2026-04-22T21:41:06.200Z","repository":{"id":228252902,"uuid":"773498318","full_name":"sofiane-abou-abderrahim/react-the-almost-final-countdown","owner":"sofiane-abou-abderrahim","description":"Discover a captivating ReactJS demo showcasing advanced features like Refs and Portals. Play the Almost Final Countdown game, where players challenge themselves with timer tasks, utilizing direct DOM access, dynamic value management, and component APIs. Experience seamless modal rendering with Portals. Dive into the code and explore the magic!","archived":false,"fork":false,"pushed_at":"2024-04-04T01:58:01.000Z","size":147,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-17T15:55:56.811Z","etag":null,"topics":["components","create-portal","dom-manipulation","forwardref","fragments","frontend","javascript","portals","react","reactjs","refs","state-management","states","timer-functionality","useimperativehandle","useref","usestate","webdevelopment"],"latest_commit_sha":null,"homepage":"https://sofiane-abou-abderrahim.github.io/react-the-almost-final-countdown/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sofiane-abou-abderrahim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-03-17T20:24:01.000Z","updated_at":"2024-03-20T20:42:07.000Z","dependencies_parsed_at":"2024-03-17T21:51:05.101Z","dependency_job_id":null,"html_url":"https://github.com/sofiane-abou-abderrahim/react-the-almost-final-countdown","commit_stats":null,"previous_names":["sofiane-abou-abderrahim/react-the-almost-final-countdown"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sofiane-abou-abderrahim/react-the-almost-final-countdown","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sofiane-abou-abderrahim%2Freact-the-almost-final-countdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sofiane-abou-abderrahim%2Freact-the-almost-final-countdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sofiane-abou-abderrahim%2Freact-the-almost-final-countdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sofiane-abou-abderrahim%2Freact-the-almost-final-countdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sofiane-abou-abderrahim","download_url":"https://codeload.github.com/sofiane-abou-abderrahim/react-the-almost-final-countdown/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sofiane-abou-abderrahim%2Freact-the-almost-final-countdown/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32156606,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T17:06:48.269Z","status":"ssl_error","status_checked_at":"2026-04-22T17:06:19.037Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["components","create-portal","dom-manipulation","forwardref","fragments","frontend","javascript","portals","react","reactjs","refs","state-management","states","timer-functionality","useimperativehandle","useref","usestate","webdevelopment"],"created_at":"2025-02-09T08:36:23.597Z","updated_at":"2026-04-22T21:41:06.175Z","avatar_url":"https://github.com/sofiane-abou-abderrahim.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Refs \u0026 Portals\n\n## Advanced DOM Access \u0026 Value Management\n\n# Tasks\n\n- Accessing DOM Elements with Refs\n- Managing Values with Refs\n- Exposing API Functions from Components\n- Detaching DOM Rendering from JSX Structure with Portals\n\n# Steps\n\n## 0. Module Introduction \u0026 Starting Project\n\n1. run `npm install`\n2. run `npm run dev`\n3. create `README.md`\n\n## 1. Repetition: Managing User Input with State (Two-Way-Binding)\n\n1. use `useState()` and two-way-binding in `Player.jsx`\n\n## 2. Introducing Refs: Connecting \u0026 Accessing HTML Elements via Refs\n\n1. replace `useState()` with `useRef()` in `Player.jsx` because it is more convenient\n\n## 3. Manipulating the DOM via Refs\n\n1. use `useRef()` to clear the input in `Player.jsx`\n\n## 4. Adding Challenges to the Demo Project\n\n1. create `TimerChallenge.jsx` component\n2. output `\u003cTimerChallenge /\u003e` components in `App.jsx`\n\n## 5. Setting Timers \u0026 Managing State\n\n1. use `useState()` to set a timer in `TimerChallenge.jsx`\n2. render UI dynamically\n\n## 6. Using Refs for More Than \"DOM Element Connections\"\n\n1. use `useRef()` in `TimerChallenge.jsx` to store the `timer` value without resetting it when the component is reexecuted\n\n## 7. Adding a Modal Component\n\n1. create `ResultModal.jsx` component\n2. output the `\u003cResultModal /\u003e` component in `TimerChallenge.jsx`\n\n## 8. Forwarding Refs to Custom Components\n\n1. reach out the dialog in `ResultModal` from `TimerChallenge.jsx` with help of `useRef()`\n2. forward the ref defined in `TimerChallenge.jsx` to the dialog element in `ResultModal.jsx` with help of the `forwardRef` function\n3. use this dialog in `TimerChallenge.jsx`\n\n## 9. Exposing Component APIs via the useImperativeHandle Hook\n\n1. detach the `TimerChallenge.jsx` component from the `dialog` element from the ``ResultModal.jsx` component with help of `useImperativeHandle()`\n\n## 10. More Examples: When To Use Refs \u0026 State\n\n1. measure how much time is left on an ongoing basis with `setInterval()` instead of `setTimeout` in `TimerChallenge.jsx`\n2. use `clearInterval()` instead of `clearTimeout()`\n\n## 11. Sharing State Across Components\n\n1. forward the correct information to the modal by replacing the `result` prop with the `remainingTime` prop\n2. use the `remainingTime` prop to calculate the score or find out if the user lost in `ResultModal.jsx`\n3. add a `handleReset` function to reset the remaining time correctly\n4. trigger the `handleReset()` function through a `onReset` prop from `ResultModal.jsx`\n\n## 12. Enhancing the Demo App \"Result Modal\"\n\n1. calculate the score in `ResultModal.jsx`\n2. output the score dynamically\n\n## 13. Closing the Modal via the ESC (Escape) Key\n\n1. add the built-in `onClose` prop to the `\u003cdialog\u003e` element and bind it to the `onReset` prop value\n\n## 14. Introducing \u0026 Understanding \"Portals\"\n\n1. use the `createPortal()` function imported from `react-dom` on the `\u003cdialog\u003e` element in `ResultModal.jsx`\n2. attach the modal to the `\u003cdiv\u003e` with an `id` of `modal` in `index.html`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsofiane-abou-abderrahim%2Freact-the-almost-final-countdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsofiane-abou-abderrahim%2Freact-the-almost-final-countdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsofiane-abou-abderrahim%2Freact-the-almost-final-countdown/lists"}