npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-pure-lifecycle

v3.0.0

Published

Add pure function lifecycle methods to any React component

Downloads

3,283

Readme

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

import React from 'react';
import lifecycle from 'react-pure-lifecycle';

// create your lifecycle methods
const componentDidMount = (props) => {
  console.log('I mounted! Here are my props: ', props);
};

// make them properties on a standard object
const methods = {
  componentDidMount
};

const FunctionalComponent = ({children}) => {
  return (
    <div>
      {children}
    </div>
  );
};

// decorate the component
export default lifecycle(methods)(FunctionalComponent);

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

import React, {
  Component
} from 'react';
import lifecycle from 'react-pure-lifecycle';

const componentDidUpdate = (props, previousProps) => {
  console.log('I updated! Here are my current and previous props: ', props, previousProps);
};

const methods = {
  componentDidUpdate
};

@lifecycle(methods)
class ComponentClass extends Component {
  render() {
    const {
      children
    } = this.props;

    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 PureComponents.

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):

import React from 'react';
import {
  shouldComponentUpdate
} from 'react-pure-lifecycle';

const onlyUpdateIfChanged = (props, nextProps) => {
  return props.children !== nextProps.children;
};

const FunctionalComponent = ({children}) => {
  return (
    <div>
      {children}
    </div>
  );
};

// decorate the component
export default shouldComponentUpdate(onlyUpdateIfChanged)(FunctionalComponent);

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:

import React from 'react';
import PropTypes from 'prop-types';
import lifecycle from 'react-pure-lifecycle';

const methods = {
  getChildContext(props) {
    return {
      foo: 'bar'
    };
  }
};

const Foo = () => {
  return (
    <div>
      Hello!
    </div>
  );
};

Foo.childContextTypes = {
  foo: PropTypes.string.isRequired
};

export default lifecycle(methods, options)(Foo);

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:

import React from 'react';
import lifecycle from 'react-pure-lifecycle';

const methods = {
  componentDidUpdate(previousProps) {
    console.log('Normally the first argument would be the currentProps,' previousProps);
  }
};
const options = {
  injectProps: false
};

const Foo = () => {
  return (
    <div>
      Hello!
    </div>
  );
};

export default lifecycle(methods, options)(Foo);

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.

import React from 'react';
import lifecycle from 'react-pure-lifecycle';

const methods = {
  componentDidMount(props) {
    console.log('Mounted with props: ', props)
  }
};
const options = {
  usePureComponent: false
};

const Foo = () => {
  return (
    <div>
      Hello!
    </div>
  );
};

export default lifecycle(methods, options)(Foo);

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 with NODE_ENV set to development and source map
  • build:minifed => run webpack to build minified JS with NODE_ENV set to production
  • clean => run rimraf on both lib and dist
  • lint => run ESLint against all files in the src folder
  • prepublish => runs prepubish:compile
  • prepublish:compile => run clean, lint, test, transpile, build, and build-minified
  • start => run webpack dev server to run example app (playground!)
  • test => run AVA test functions with NODE_ENV=test
  • test:coverage => run test with nyc to get output of code coverage
  • test:watch => run test, but with persistent watcher
  • transpile => run babel against all files in src to create files in lib