{"id":14385007,"url":"https://github.com/troch/hocompose","last_synced_at":"2025-04-19T11:56:55.239Z","repository":{"id":57264769,"uuid":"53365037","full_name":"troch/hocompose","owner":"troch","description":"Compose HOCs like a boss","archived":false,"fork":false,"pushed_at":"2016-09-07T09:33:26.000Z","size":68,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-23T22:23:39.731Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/troch.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}},"created_at":"2016-03-07T22:52:52.000Z","updated_at":"2017-08-01T02:42:25.000Z","dependencies_parsed_at":"2022-08-25T02:52:18.283Z","dependency_job_id":null,"html_url":"https://github.com/troch/hocompose","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troch%2Fhocompose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troch%2Fhocompose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troch%2Fhocompose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troch%2Fhocompose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troch","download_url":"https://codeload.github.com/troch/hocompose/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241421166,"owners_count":19960238,"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":[],"created_at":"2024-08-28T18:01:51.368Z","updated_at":"2025-03-01T20:31:16.430Z","avatar_url":"https://github.com/troch.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# hocompose\n\n[![npm version](https://badge.fury.io/js/hocompose.svg)](https://badge.fury.io/js/hocompose)\n[![Build Status](https://travis-ci.org/troch/hocompose.svg?branch=master)](https://travis-ci.org/troch/hocompose)\n\n\u003e A library to compose higher-order components into one.\n\n__Note: 1.0.0 is a rewrite__\n\n## Higher-order components\n\nUsing Higher-Order Components (HOCs) in React is great for composition. They allow to decouple rendering logic from life-cycle logic. HOCs are good for extracting logic from components, so it can be applied to other components without duplicating code.\n\nSharing a specific component behaviour between many components is easy with higher-order components. However, because of nesting, adding multiple behaviours to a component is done at the expense of component instances.\n\n\n## Composition\n\nNesting rendering logic makes total sense, this is how one builds a UI consisting of a tree of components. But, why should one follow the same pattern to add a series of behaviours to a component?\n\nThis is what __hocompose__ enables: composing behaviours together in only one higher-order component. Think of it as the best of higher-order components, decorators and mixins.\n\n\n## Installation and usage\n\n```sh\nnpm install --save hocompose\n```\n\n```js\nimport compose from 'hocompose';\nimport pure from 'hocompose/behaviours/pure';\nimport setContext from 'hocompose/behaviours/setContext';\nimport getContext from 'hocompose/behaviours/getContext';\n```\n\n## Key concepts\n\n- Only functions with closures, __hocompose__ is thisless\n- State values are serialised to props\n- `componentWillMount` and `componentDidMount` functions can both return functions executed in `componentWillUnmount`\n\n## Docs\n\n* [Behaviours](docs/behaviours/index.md)\n   * [Overview](docs/behaviours/overview.md)\n   * [API](docs/behaviours/api.md)\n   * [Composition](docs/behaviours/composition.md)\n* [Examples](docs/examples/index.md)\n   * [Event subscription](docs/examples/event-subscription.md)\n   * [Event handlers](docs/examples/event-handlers.md)\n   * [Redux store subscription](docs/examples/redux-store-subscription.md)\n\n\n## Quick example\n\n```js\nimport React from 'react';\nimport compose from 'hocompose';\nimport pure from 'hocompose/behaviours/pure';\n\nconst windowSizeBehaviour = (model) =\u003e {\n    const buildState = () =\u003e ({\n        width: window.innerWidth,\n        height: window.innerHeight\n    });\n\n    return {\n        state: buildState(),\n        componentDidMount(model, setState) {\n            const resizeHandler = () =\u003e setState(buildState());\n            \n            window.addEventListener('resize', resizeHandler);\n\n            // Return an unmount function\n            return () =\u003e window.removeEventListener('resize', resizeHandler);\n        }\n    };\n};\n\nconst MyView = (props) =\u003e \u003cdiv\u003eThis is my view, { props.width }x{ props.height }\u003c/div\u003e;\n\nexport default compose(pure, windowSizeBehaviour)(MyView);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroch%2Fhocompose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroch%2Fhocompose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroch%2Fhocompose/lists"}