{"id":32563065,"url":"https://github.com/blevs/react-compose","last_synced_at":"2026-02-22T23:07:39.704Z","repository":{"id":39127347,"uuid":"263188634","full_name":"Blevs/react-compose","owner":"Blevs","description":"Learn how to compose React logic with HOC's, Render Props, Hooks and Context","archived":false,"fork":false,"pushed_at":"2023-01-05T20:14:25.000Z","size":4082,"stargazers_count":4,"open_issues_count":20,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-29T02:56:48.986Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","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/Blevs.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}},"created_at":"2020-05-12T00:14:00.000Z","updated_at":"2022-07-22T20:46:33.000Z","dependencies_parsed_at":"2023-02-04T14:01:07.971Z","dependency_job_id":null,"html_url":"https://github.com/Blevs/react-compose","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Blevs/react-compose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Freact-compose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Freact-compose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Freact-compose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Freact-compose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Blevs","download_url":"https://codeload.github.com/Blevs/react-compose/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Blevs%2Freact-compose/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29730315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T20:09:16.275Z","status":"ssl_error","status_checked_at":"2026-02-22T20:09:13.750Z","response_time":110,"last_error":"SSL_read: 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":[],"created_at":"2025-10-29T02:56:23.175Z","updated_at":"2026-02-22T23:07:39.664Z","avatar_url":"https://github.com/Blevs.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Composition - HOC's, Render props, Hooks and Context\n\nIt is easy to share logic between React components, as long as it doesn't involve state. Stateful logic is tied deeply to the component itself. This is a problem for logic that we wish to share between many components. Our example today will be a toggle.\n\nSimple enough, right? All we need is a boolean in state, and a function to flip. However, to avoid writing that a million times we embark upon a significant journey with many possible outcomes.\n\nThere are a number of common patterns\n\n- Higher Order Components \n\nThe goal of this pattern is to wrap our view layer inside a pre-built and re-usable component that contains our stateful layer. \n\n```js\nconst ToggleComponent = withToggle(StatelessToggleComponent)\n```\n\n`withToggle` creates a new component wherein `StatelessToggleComponent` receives the props `isOn` and `toggle`, or equivalents, from a parent component.\n\n- Render Props\n\n```\n\u003cToggleComponent\u003e\n  {({ isOn, toggle}) =\u003e (\n    \u003cbutton onClick={toggle}\u003e\n      {inOn ? 'On' : 'off'}\n    \u003c/button\u003e\n  )}\n\u003c/ToggleComponent\u003e\n```\n\nRender props (in this case, render children) follow a similar pattern, but can be a bit more flexible. We provide a function, on the fly, that takes the toggle functionality as arguments.\n\n- Hooks\n\n```\nconst ToggleComponent () =\u003e {\n  ...\n  const { isOn, toggle } = useToggle();\n  ...\n  return (\n    \u003cbutton onClick={toggle}\u003e\n      {inOn ? 'On' : 'off'}\n    \u003c/button\u003e\n  );\n}\n```\n\nHooks are a relatively new method for composing stateful logic now that functional components can hold state. This allows us to directly share the state and logic between components without wrapping our component.\n\n- Context\n\n```\nconst ToggleButton () =\u003e {\n  const { isOn, toggle } = useToggleContext();\n\n  return (\n    \u003cbutton onClick={toggle}\u003e\n      {inOn ? 'On' : 'off'}\n    \u003c/button\u003e\n  );\n}\nconst WhileOn ({ children }) =\u003e {\n  const { isOn } = useToggleContext();\n  if (isOn) {\n   return children;\n  }\n  return null;\n}\n\n...\n\u003cToggleProvider\u003e\n  \u003cToggleButton /\u003e\n  ....\n  \u003cWhileOn\u003e\n    The toggle is on\n  \u003c/WhileOn\u003e\n\u003c/ToggleProvider\u003e\n```\n\nWhile Context has existed longer than hooks it is a bit more ergonomic. (Previously, you had to use render props.) This allows us to compose and _share_ the state and logic with many components at once.\n\nThis involves some amount of DOM manipulation, which is a good thing! We can't forget that React exists in our web browser, our vanilla DOM and JS knowledge is still valuable, and React cannot abstract *everything* away.\n\n## Goals\n\n* [ ] Create a class based Toggle component\n* [ ] Create a function based Toggle component\n* [ ] Share this logic with a Higher Order Component\n* [ ] Share this logic with Render Props\n* [ ] Share this logic with a Custom Hook\n* [ ] Share this logic with Context\n\n## Stretch Goals\n\n* [ ] Understand why the React Router has both a `component` and a `render` prop. It may help to take a look at the source code. Or, google it.\n\n## Notes\n\n* Another pattern may have occurred to you. A shockingly simple pattern. What if we isolate all of our logic from our `setState`, or equivalent, functions. What if we remove those side-effects and have our logic simply take the previous state, and output the new state? A pure, functional system. Then we won't have to worry at all about the specifics of React. \n\nSounds wonderful, right? Well, you just invented the reducer pattern. We won't talk about it today, but we will revisit it with a later project on `useReducer` and `Redux`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblevs%2Freact-compose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblevs%2Freact-compose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblevs%2Freact-compose/lists"}