{"id":27522601,"url":"https://github.com/jul-sh/hook-into-props","last_synced_at":"2025-04-18T10:25:49.642Z","repository":{"id":41796981,"uuid":"169903220","full_name":"jul-sh/hook-into-props","owner":"jul-sh","description":"Tiny HoC to use React hooks with class components.","archived":false,"fork":false,"pushed_at":"2023-02-28T11:19:35.000Z","size":1995,"stargazers_count":47,"open_issues_count":20,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T00:34:26.154Z","etag":null,"topics":["codesandbox","higher-order-component","hooks","javascript","react"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/hook-into-props","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jul-sh.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2019-02-09T19:11:43.000Z","updated_at":"2023-04-28T12:03:21.000Z","dependencies_parsed_at":"2024-10-24T02:08:01.800Z","dependency_job_id":"291ac051-105b-4cec-9b58-0214ae5526f7","html_url":"https://github.com/jul-sh/hook-into-props","commit_stats":{"total_commits":85,"total_committers":4,"mean_commits":21.25,"dds":"0.10588235294117643","last_synced_commit":"0ed6a0d8b691d177a2d6cb1a434e3d0129c58900"},"previous_names":["juliettepretot/hookintoprops"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jul-sh%2Fhook-into-props","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jul-sh%2Fhook-into-props/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jul-sh%2Fhook-into-props/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jul-sh%2Fhook-into-props/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jul-sh","download_url":"https://codeload.github.com/jul-sh/hook-into-props/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248774977,"owners_count":21159534,"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":["codesandbox","higher-order-component","hooks","javascript","react"],"created_at":"2025-04-18T10:25:48.807Z","updated_at":"2025-04-18T10:25:49.635Z","avatar_url":"https://github.com/jul-sh.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚢 hook-into-props\n\n## Introduction\n\n```jsx\nimport React from 'react'\nimport hookIntoProps from 'hook-into-props'\n\nclass DisplayWindowSize extends React.Component {\n  render() {\n    return this.props.windowSize\n  }\n}\n\nconst useHooks = () =\u003e ({ windowSize: useWindowSize() })\n\nexport default hookIntoProps(useHooks)(DisplayWindowSize)\n```\n\n## Installation\n\nYou can install it via `npm i hook-into-props`. (200 bytes + 1kb dependencies. See [bundle-phobia](https://bundlephobia.com/result?p=hook-into-props))\n\nAlternatively you can copy the [source code](index.js), it's only a few lines. If you don't feel like adding any abstractions at all, check out [without-abstractions](#without-abstractions).\n\n## Examples\n\n### Using props with hooks\n\n```jsx\nimport React from 'react'\nimport hookIntoProps from 'hook-into-props'\n\nclass SearchResults extends React.Component {\n  render() {\n    this.props.isLoading ? 'loading' : this.props.searchResults\n  }\n}\n\nconst useHooks = props =\u003e {\n  const [isLoading, searchResults] = useFetch(\n    `https://foo.com/?search=${props.searchTerm}`\n  )\n\n  return { isLoading, searchResults }\n}\n\nexport default hookIntoProps(useHooks)(SearchResults)\n```\n\n### Using multiple hooks\n\n```jsx\nimport React from 'react'\nimport hookIntoProps from 'hook-into-props'\nimport { ReferralCode, TimezoneOffset, FeatureList } from '~/contexts'\n\nclass UserForm extends React.Component {\n  componentDidMount() {\n    const { referralCode, timezoneOffset, featureList } = this.props\n    // ...\n  }\n  render() {\n    // ...\n  }\n}\n\nconst useHooks = () =\u003e ({\n  referralCode: useContext(ReferralCode),\n  timezoneOffset: useContext(TimezoneOffset),\n  featureList: useContext(FeatureList)\n})\n\nexport default hookIntoProps(useHooks)(UserForm)\n```\n\n### Exporting Higher-Order-Components\n\n```jsx\nexport const withWindowSize = hookIntoProps(() =\u003e ({\n  windowSize: useWindowSize()\n}))\n```\n\n## Under the hood\n\nThat's the (simplified) [source code](index.js):\n\n```jsx\nfunction hookIntoProps(useHooks) {\n  return function(Component) {\n    return function HooksProvider(props) {\n      return \u003cComponent {...props} {...useHooks(props)} /\u003e\n    }\n  }\n}\n```\n\n(The hook calls in `useHooks` are only executed when `useHooks` is called inside of `HooksProvider`. At that point they are called within a function component, where we can use hooks. The results of our hook calls are passed as props)\n\n## Alternatives\n\n### Without abstractions\n\nTo avoid any helpers at all, we could inline a functional component in the export statement.\n\n```jsx\nimport React from 'react'\n\nclass DisplayWindowSize extends React.Component {\n  render() {\n    return this.props.isLoading ? 'loading' : this.props.searchResults\n  }\n}\n\nexport default function HooksProvider(props) {\n  const [isLoading, searchResults] = useFetch(\n    `https://foo.com/?search=${props.searchTerm}`\n  )\n\n  return (\n    \u003cDisplayWindowSize\n      {...props}\n      isLoading={isLoading}\n      searchResults={searchResults}\n    /\u003e\n  )\n}\n```\n\nThis can work very well for simple cases. It lays out the logic in a verbose manner.\n\nThere's some caveats to this though. First, the export must be a named function declaration, as else you end up with an odd React tree of `Unkown` components. Secondly, with more complexity, this can become harder to read. It becomes more difficult to see at a glance which component is really being exported. Also, you'll have to remember to manually spread props every time.\n\n### Render-props\n\nWe could also create a simple Component that allows us to consume hooks through render-props:\n\n```jsx\nimport React from 'react'\n\nconst HookProvider = ({ children, useHooks }) =\u003e children(useHooks())\n\nclass DisplayWindowSize extends React.Component {\n  render() {\n    return (\n      \u003cHookProvider useHooks={() =\u003e useWindowSize()}\u003e\n        {windowSize =\u003e \u003cspan\u003e{windowSize}\u003c/span\u003e}\n      \u003c/HookProvider\u003e\n    )\n  }\n}\n```\n\nThis looks clean, but we won't have access to the hook result in our other class methods. This can make it poor choice for supporting existing class components.\n\n### Rewriting your class as a function component\n\nYou could also refactor your class component and directly use hooks inside your new function component. However, refactoring existing classes isn't always an option.\n\nBeing able to use hooks with your old code can be convenient. It actually allows you to refactor existing higher order components to hooks without breaking support for your existing class components.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjul-sh%2Fhook-into-props","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjul-sh%2Fhook-into-props","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjul-sh%2Fhook-into-props/lists"}