react-pure-lifecycle
Add lifecycle methods to your functional components with purity
Table of contents
Installation
$ npm i react-pure-lifecycle --save
Usage
The primary use case for this decorator is with functional components, however you can use it with Component
and PureComponent
classes as well.
Functional components
;; // create your lifecycle methodsconst componentDidMount = { console;}; // make them properties on a standard objectconst methods = componentDidMount; const FunctionalComponent = { return <div> children </div> ;}; // decorate the componentmethodsFunctionalComponent;
The complete list of lifecycle methods are supported, minus constructor
(if you want to fire something as early as possible, use componentWillMount
). The first parameter passed to each lifecycle method is the component's current props
, and then all standard parameters for that given lifecycle method follow. For a detailed explanation of each of the methods and the parameters they expect, check the React documentation.
You can also add options to customize the use of the decorator, see Options for more details.
Class components
;; const componentDidUpdate = { console;}; const methods = componentDidUpdate; @ { const children } = thisprops; return <div> children </div> ; }
Not a whole lot of gain here other than the fact that you now have a pure function that you can test independently (no need to create an instance). This decoration method will also work on PureComponent
s.
Individual method decorators
Each lifecycle method is also provided as their own decorator, if you just want to bind a single method (receives the method itself instead of an object of methods):
;; const onlyUpdateIfChanged = { return propschildren !== nextPropschildren;}; const FunctionalComponent = { return <div> children </div> ;}; // decorate the componentonlyUpdateIfChangedFunctionalComponent;
If you want to provide options to these specific method decorators, you can pass them as the second argument.
Adding child context
In addition to providing the standard lifecycle methods, starting in 2.x.x
you can add child context to functional components (something normally React
disallows). Example:
;;; const methods = { return foo: 'bar' ; }; const Foo = { return <div> Hello! </div> ;}; FoochildContextTypes = foo: PropTypesstringisRequired; methods optionsFoo;
Like standard lifecycle methods, this will also apply to components instantiated via the class method, with the only difference from standard behavior being the injection of the props
argument.
Options
Additional options can be passed as the second parameter to the decorator, with the following shape:
injectProps: boolean // should the component's props be injected as first argument (default: true) usePureComponent: boolean // should the component rendered be a PureComponent (default: true)
injectProps
By default, all lifecycle methods will receive the component's current props
as the first argument, and then all standard arguments for the given lifecycle method following. If you would like to disable this injection, set injectProps
to false
:
;; const methods = { console; };const options = injectProps: false; const Foo = { return <div> Hello! </div> ;}; methods optionsFoo;
usePureComponent
By default, functional components that have the decorator applied will use PureComponent
as the foundation of the HOC, allowing for the same render-limiting performance optimizations that a PureComponent
class has. If you would like to disable this and instead use the standard Component
class for the HOC, set usePureComponent
to false
.
;; const methods = { console };const options = usePureComponent: false; const Foo = { return <div> Hello! </div> ;}; methods optionsFoo;
Please note that this option will only affect functional components; if you apply the decorator to a standard component class, it will use the same component class that was decorated.
Development
Standard stuff, clone the repo and npm install
dependencies. The npm scripts available:
build
=> run webpack to build unminified JS withNODE_ENV
set todevelopment
and source mapbuild:minifed
=> run webpack to build minified JS withNODE_ENV
set toproduction
clean
=> runrimraf
on bothlib
anddist
lint
=> run ESLint against all files in thesrc
folderprepublish
=> runsprepubish:compile
prepublish:compile
=> runclean
,lint
,test
,transpile
,build
, andbuild-minified
start
=> run webpack dev server to run example app (playground!)test
=> run AVA test functions withNODE_ENV=test
test:coverage
=> runtest
with nyc to get output of code coveragetest:watch
=> runtest
, but with persistent watchertranspile
=> run babel against all files insrc
to create files inlib