{"id":13739738,"url":"https://github.com/strayiker/babel-plugin-hoist-facc","last_synced_at":"2025-04-11T19:51:59.796Z","repository":{"id":57188826,"uuid":"148944825","full_name":"strayiker/babel-plugin-hoist-facc","owner":"strayiker","description":"Babel plugin to hoist Function as Child Component","archived":false,"fork":false,"pushed_at":"2018-10-06T18:45:24.000Z","size":50,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-01T07:13:46.539Z","etag":null,"topics":["babel-plugin","react"],"latest_commit_sha":null,"homepage":"","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/strayiker.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":"2018-09-15T22:31:07.000Z","updated_at":"2024-07-16T15:00:26.000Z","dependencies_parsed_at":"2022-08-28T12:51:36.787Z","dependency_job_id":null,"html_url":"https://github.com/strayiker/babel-plugin-hoist-facc","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/strayiker%2Fbabel-plugin-hoist-facc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strayiker%2Fbabel-plugin-hoist-facc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strayiker%2Fbabel-plugin-hoist-facc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strayiker%2Fbabel-plugin-hoist-facc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/strayiker","download_url":"https://codeload.github.com/strayiker/babel-plugin-hoist-facc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237056750,"owners_count":19248052,"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":["babel-plugin","react"],"created_at":"2024-08-03T04:00:37.011Z","updated_at":"2025-02-04T04:15:29.332Z","avatar_url":"https://github.com/strayiker.png","language":"JavaScript","funding_links":[],"categories":["Plugins"],"sub_categories":["React"],"readme":"# babel-plugin-hoist-facc\n\n\u003e Treat [FACC](https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9) as value types and hoist them to the highest scope\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @babel/core babel-plugin-hoist-facc\n```\n\nor using yarn:\n\n```sh\nyarn add @babel/core babel-plugin-hoist-facc --dev\n```\n\n## What problem it solves?\n\nIt solves the problem of rendering optimization, which comes with `FaCC` pattern. In a few words: Function as Child Component can't be optimized by `shouldComponentUpdate` because the child function is always changes on render.\n\nThis plugin hoist the child function to highest possible scope to prevent its changes.\n\n## Example\n\n```javascript\nclass extends React.Component {\n  render() {\n    return \u003cFaCC\u003e{() =\u003e \u003cdiv /\u003e}\u003c/FaCC\u003e; // arrow function changes on each render\n  }\n}\n```\n\n⇩⇩⇩\n\n```javascript\nvar _ref = () =\u003e \u003cdiv /\u003e;\n\nclass extends React.Component {\n  render() {\n    return \u003cFaCC\u003e{_ref}\u003c/FaCC\u003e; // now it's constant\n  }\n}\n```\n\n## Options\n\n| Option             | Defaults | Description                                                                                                                                                                                                                              |\n| ------------------ | :------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| unsafeHoistInClass |  false   | When `true`, enables the hoisting of FaCC children function, which refers to `this`, to the class constructor. Potentially it is unsafe due to context losing issue, but in regular React life this should`t happens. See example below. |\n| warnIfCantHoist    |  false   | When `true`, display a warnings about child functions that couldn't be hoisted.                                                                                                                                                          |\n| loose              |  false   | When `true`, class properties are compiled to use an assignment expression instead of Object.defineProperty.                                                                                                                             |\n\n## More examples\n\n`[\"hoist-facc\", { unsafeHoistInClass: true, loose: true }]`\n\n```javascript\nclass extends React.Component {\n  handleClick = () =\u003e {};\n\n  render() {\n    return \u003cFaCC\u003e{() =\u003e \u003cbutton onClick={this.handleClick} /\u003e}\u003c/FaCC\u003e;\n  }\n}\n```\n\n⇩⇩⇩\n\n```javascript\nclass extends React.Component {\n  constructor(...args) {\n    super(...args);\n\n    this.handleClick = () =\u003e {};\n    this._ref = () =\u003e \u003cbutton onClick={this.handleClick} /\u003e;\n  }\n\n  render() {\n    return \u003cFaCC\u003e{this._ref}\u003c/FaCC\u003e;\n  }\n}\n```\n\n## Pitfalls\n\nThere some cases it can't be hoisted automagically.\n\n```javascript\nclass extends React.Component {\n  render() {\n    const { id, label } = this.props;\n\n    return \u003cFaCC\u003e{() =\u003e \u003cdiv id={id}\u003e{label}\u003c/div\u003e}\u003c/FaCC\u003e;\n  }\n}\n```\n\nThe above code will not be transformed, because the `id` and `label` from the higher scope is used inside `FaCC`.\nYou should proxy the props to the child function or access props directly trought `this` keyword to avoid this.\n\n```javascript\nclass extends React.Component {\n  render() {\n    return (\n      \u003cFaCC {...this.props}\u003e\n        {({ id }) =\u003e (\n          \u003cdiv id={id}\u003e{this.props.label}\u003c/div\u003e\n        )}\n      \u003c/FaCC\u003e\n    );\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrayiker%2Fbabel-plugin-hoist-facc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstrayiker%2Fbabel-plugin-hoist-facc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrayiker%2Fbabel-plugin-hoist-facc/lists"}