maco
This script allows you to avoid using javascript "classes" when dealing with React. This enables true encapsulation via closures.
Example
Let's take a look at simple Counter
component:
// counter.js filevar React = ;moduleexports = counter React;{// we will increase counter `i` every second:var i = 0;;{i++; // `i` is truly encapsulated. Nobody but this counter can modify it.x; // tell React to enqueue the update.}// tell React how to render this componentx {// notice regular props, as well as internal `i`:return <h2>xpropsname: i</h2>;}}
Now that we have a Counter, no extra logic is required to use it from react application:
// app.js filevar ReactDOM = ;var Counter = ;ReactDOM;
defaultProps and propTypes
When authoring react components it's often desirable to set defaultProps
and
propTypes
. Facebook recommends
to use constructor function, so let's do it:
// counter.js filevar React = ;var Counter = counter React;CounterpropTypes = name: ReactPropTypesstring ;CounterdefaultProps = name: 'My counter' ;moduleexports Counter;
This will result in standard behavior for propTypes
validation and initial
value assignment.
demo
The demo source code is available here. Running example is here.
single React instance
React instance is required to avoid multiple versions of React in the same
bundle. For your convenience you can bind maco
to your own React instance
like so:
// in your local project, let's say lib/maco.js is the name of this filevar React = ;moduleexports = ;// now any other file (let's say counter.js) in your project can domoduleexports = counter;{var i = 42;x { return <h2>Hello i</h2> }}
Why?
This approach has couple benefits:
- Unlike prototype-based classes, maco allows you to truly encapsulate data: It's just a regular javascript closure.
- No need to remember what is
this
anymore. The component instance is passed as an argument to the function. In the example above it's calledx
. - Dead simple.
How?
maco
is very simple wrapper on top of React.Component
. Actually, it's only
several lines long:
{;return Maker;{Makerprototypeconstructor;factory;}}
We create a new child of React.Component
and from the constructor invoke
the "factory" callback. Factory callback is bound to the current component.
In other words this
will be the same as what you'd normally expect from
React.
I'm passing current component instance (this
) as an argument to the factory function
. It is just for your convenience, so you don't have to do silly
that = this
dance.
install
npm install maco
license
MIT