https://github.com/strayiker/babel-plugin-hoist-facc
Babel plugin to hoist Function as Child Component
https://github.com/strayiker/babel-plugin-hoist-facc
babel-plugin react
Last synced: over 1 year ago
JSON representation
Babel plugin to hoist Function as Child Component
- Host: GitHub
- URL: https://github.com/strayiker/babel-plugin-hoist-facc
- Owner: strayiker
- License: mit
- Created: 2018-09-15T22:31:07.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-10-06T18:45:24.000Z (almost 8 years ago)
- Last Synced: 2025-02-01T07:13:46.539Z (over 1 year ago)
- Topics: babel-plugin, react
- Language: JavaScript
- Homepage:
- Size: 48.8 KB
- Stars: 8
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-babel - babel-plugin-hoist-facc - Transforms function as child components to hoist the children function to highest scope. (Plugins / React)
README
# babel-plugin-hoist-facc
> Treat [FACC](https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9) as value types and hoist them to the highest scope
## Install
Using npm:
```sh
npm install --save-dev @babel/core babel-plugin-hoist-facc
```
or using yarn:
```sh
yarn add @babel/core babel-plugin-hoist-facc --dev
```
## What problem it solves?
It 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.
This plugin hoist the child function to highest possible scope to prevent its changes.
## Example
```javascript
class extends React.Component {
render() {
return {() =>
}; // arrow function changes on each render
}
}
```
⇩⇩⇩
```javascript
var _ref = () =>
;
class extends React.Component {
render() {
return {_ref}; // now it's constant
}
}
```
## Options
| Option | Defaults | Description |
| ------------------ | :------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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. |
| warnIfCantHoist | false | When `true`, display a warnings about child functions that couldn't be hoisted. |
| loose | false | When `true`, class properties are compiled to use an assignment expression instead of Object.defineProperty. |
## More examples
`["hoist-facc", { unsafeHoistInClass: true, loose: true }]`
```javascript
class extends React.Component {
handleClick = () => {};
render() {
return {() => };
}
}
```
⇩⇩⇩
```javascript
class extends React.Component {
constructor(...args) {
super(...args);
this.handleClick = () => {};
this._ref = () => ;
}
render() {
return {this._ref};
}
}
```
## Pitfalls
There some cases it can't be hoisted automagically.
```javascript
class extends React.Component {
render() {
const { id, label } = this.props;
return {() =>
{label}};
}
}
```
The above code will not be transformed, because the `id` and `label` from the higher scope is used inside `FaCC`.
You should proxy the props to the child function or access props directly trought `this` keyword to avoid this.
```javascript
class extends React.Component {
render() {
return (
{({ id }) => (
{this.props.label}
)}
);
}
}
```