{"id":23399715,"url":"https://github.com/ch0ripain/react-refs-and-portals","last_synced_at":"2025-04-08T19:53:18.186Z","repository":{"id":265160025,"uuid":"884031876","full_name":"ch0ripain/react-refs-and-portals","owner":"ch0ripain","description":"🔗 React Refs \u0026 Portals 🌀","archived":false,"fork":false,"pushed_at":"2024-11-28T01:10:28.000Z","size":123,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T15:47:06.090Z","etag":null,"topics":["frontend","react","react-portals","react-refs","reactjs","web-development"],"latest_commit_sha":null,"homepage":"","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/ch0ripain.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,"publiccode":null,"codemeta":null}},"created_at":"2024-11-06T02:29:47.000Z","updated_at":"2024-11-28T01:10:31.000Z","dependencies_parsed_at":"2024-11-28T02:19:48.669Z","dependency_job_id":"32bde89b-1cae-4f60-ac65-47aab60881a1","html_url":"https://github.com/ch0ripain/react-refs-and-portals","commit_stats":null,"previous_names":["ch0ripain/react-refs-and-portals"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ch0ripain%2Freact-refs-and-portals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ch0ripain%2Freact-refs-and-portals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ch0ripain%2Freact-refs-and-portals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ch0ripain%2Freact-refs-and-portals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ch0ripain","download_url":"https://codeload.github.com/ch0ripain/react-refs-and-portals/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247918936,"owners_count":21018043,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["frontend","react","react-portals","react-refs","reactjs","web-development"],"created_at":"2024-12-22T10:16:16.106Z","updated_at":"2025-04-08T19:53:18.157Z","avatar_url":"https://github.com/ch0ripain.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e🔗 React Refs and Portals 🌀\u003c/h1\u003e\n\n## 🔗 Refs 🔗\nFirst, you need to import \u003ccode\u003euseRef from 'react'\u003c/code\u003e. A \u003ccode\u003eref\u003c/code\u003e is like a persistent storage value that isn't affected by React's rendering cycle. This allows you to store values that persist over time, enabling various functionalities.\n\nFor example, if you assign a \u003ccode\u003eref\u003c/code\u003e value to a \u003ccode\u003esetInterval\u003c/code\u003e (as shown in this project), you can later clean up that interval using \u003ccode\u003eclearInterval()\u003c/code\u003e like this:\n```javascript\nconst timer = useRef()\ntimer.current = setInterval(() =\u003e {}, 100)\nclearInterval(timer.current)\n```\nA ref can also be used to call built-in methods of HTML elements when needed. For example, to open a file input, instead of triggering the method in the usual way, we can trigger it using a \u003ccode\u003eref\u003c/code\u003e on the input element, like this:\n```javascript\nconst filePickerRef = React.useRef();\n\u003cinput ref={filePickerRef} type=\"file\" /\u003e  {/* The ref attribute is built-in for all HTML elements in React */}\n\u003cbutton onClick={() =\u003e filePickerRef.current.click()}\u003ePick Image\u003c/button\u003e  {/* Triggering the click() method of the file input using the ref */}\n```\nIn this example, the \u003ccode\u003eref\u003c/code\u003e attribute is used to reference the input element. By calling \u003ccode\u003efilePickerRef.current.click()\u003c/code\u003e, we can programmatically trigger the file picker dialog instead of relying on the usual user interaction.\n\u003e [!NOTE]\n\u003e A \u003ccode\u003eref\u003c/code\u003e is a property of a component instance, and its value will not change on re-renders.\n\n## 🌀 Portals 🌀\nA portal in React allows you to render content in a different part of the DOM than where the component is defined. This is useful because, without it, for example, in this project, the \u003ccode\u003eResultModal\u003c/code\u003e might appear inside other elements due to the position of the JSX in the component tree.\n\nTo control where this content is rendered, we can use \u003ccode\u003e{ createPortal }\u003c/code\u003e, a function from \u003ccode\u003ereact-dom\u003c/code\u003e, which works like this:\n```javascript\nimport { createPortal } from 'react-dom' //2 arguments =\u003e (renderable code, target DOM element where you want to inject)\nexport default function ResultModal(...){\nreturn createPortal(\n    \u003cp\u003eRenderable content\u003c/p\u003e, \n    document.querySelector('placeWeWant') // Target element where the content will be injected\n  );}\n```\n\n## ⚙️ useImperativeHandle ⚙️ \nThe \u003ccode\u003euseImperativeHandle\u003c/code\u003e hook allows us to expose certain built-in HTML element methods (like those we’ve seen before) when working with refs. This hook helps make the code more readable and maintainable by controlling what functions or properties are accessible outside of the component.\n\n```javascript\n//We need to forward a ref from another component\nimport { forwardRef } from 'react'\n\n//Change how our component is exported\nconst ResultModal = forwardRef(function ResultModal(props, ref){}) //forwardRef receive as 2nd argument the ref coming from the other component, right next to props\nconst dialog = useRef()\nuseImperativeHandle(forwardedRef, () =\u003e {                          //first argument is the ref where then we can call this exposed methods\nreturn { someRelatedName(){ dialog.current.click() },             //The second argument of useImperativeHandle should return an object of functions. In this object, each function acts as an \"exposed method.\" These methods are named by you, and within each one, you can execute the original method (e.g., dialog.current.click()) or add additional logic as needed.\n}\n\u003cdialog ref={dialog} ...\u003e...\u003c/dialog\u003e\n})\n// In the component where we are forwarding the ref (which gives access to the exposed methods), we need a separate ref inside the parent component to actually call those methods.\n//TimerChallenge.jsx\nconst dialog = useRef()\n//pass the ref to the component\n\u003cResultModal ref={dialog} /\u003e\n//Use the expose method\nsomeFunction(){\ndialog.current.someRelatedName()\n}\n```\n---\n\u003cp align=\"center\"\u003e🐸 This project is a practice exercise I learned from the \u003ca href='https://www.udemy.com/course/react-the-complete-guide-incl-redux/?couponCode=ST7MT110524'\u003eAcademind's React Course\u003c/a\u003e 🐸\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fch0ripain%2Freact-refs-and-portals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fch0ripain%2Freact-refs-and-portals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fch0ripain%2Freact-refs-and-portals/lists"}