# hoist-non-react-methods

> Copies non-react specific methods from a child component to a parent component

Latest version **1.1.0** (published 2018-01-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install hoist-non-react-methods
pnpm add hoist-non-react-methods
yarn add hoist-non-react-methods
bun add hoist-non-react-methods
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2018-01-23 |
| First published | 2016-01-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 11 |
| Author | Elad Ossadon |
| Maintainers | elado |
| Keywords | react |

## Links

- npm: https://www.npmjs.com/package/hoist-non-react-methods
- Repository: https://github.com/elado/hoist-non-react-methods
- Homepage: https://github.com/elado/hoist-non-react-methods#readme
- Issues: https://github.com/elado/hoist-non-react-methods/issues
- npm.io page: https://npm.io/package/hoist-non-react-methods

## Dependencies (1)

- [sinon](https://npm.io/package/sinon.md) ^4.2.0

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.1.0 (latest) — 2018-01-23
- 1.0.2 — 2016-01-26
- 1.0.1 — 2016-01-26
- 1.0.0 — 2016-01-26

## README

# hoist-non-react-methods

> Copies non-react specific methods from a child component to a parent component

[![build status](https://img.shields.io/travis/elado/hoist-non-react-methods/master.svg?style=flat-square)](https://travis-ci.org/elado/hoist-non-react-methods) [![npm version](https://img.shields.io/npm/v/hoist-non-react-methods.svg?style=flat-square)](https://www.npmjs.com/package/hoist-non-react-methods) [![codeclimate](https://img.shields.io/codeclimate/github/elado/hoist-non-react-methods.svg?style=flat-square)](https://codeclimate.com/github/elado/hoist-non-react-methods)

**Inspired by @mridgway's [hoist-non-react-statics](https://github.com/mridgway/hoist-non-react-statics)**

When wrapping a component (see [Higher-Order Components](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) methods that are defined in the child component aren't accessible anymore. This module makes those methods available on the wrapper component's prototype.

## Installation

```sh
npm install hoist-non-react-methods --save
```

## When is it needed?

Components can have public methods that are accessible through their instance under parent's `refs`.

```js
class Composer extends React.Component {
  render() {
    return <input type="text" ref="input" />
  }

  focus() {
    return this.input.focus()
  }
}

class Root extends React.Component {
  render() {
    return (
      <div>
        <button onClick={e => this.refs.composer.focus()}></button>
        <Composer ref="composer" />
      </div>
    )
  }
}
```

Assuming you have a component which is decorated, the method `focus` will be lost, because the `ref` will point the decorator component.

```js
@someDecorator()
class Composer extends React.Component {
  render() {
    return <input type="text" ref="input" />
  }

  focus() {
    return this.input.focus()
  }
}

function someDecorator() {
  return function (WrappedComponent) {
    class Wrapper extends Component {
      static displayName = `Wrapper(${WrappedComponent.displayName})`

      componentWillMount() {
        // some specific logic in a decorator
      }

      render() {
        return <WrappedComponent ref="wrappedComponent" />
      }
    }

    return Wrapper
  }
}

class Root extends React.Component {
  // this.refs.composer.focus is undefined!
  render() {
    return (
      <div>
        <button onClick={e => this.refs.composer.focus()}></button>
        <Composer ref="composer" />
      </div>
    )
  }
}
```

This package provides a function that copies all the methods (prototype and static) from the wrapped component to the wrapper, but keeps all react specific methods (e.g. `componentDidMount` etc.) untouched.

```js
@someDecorator()
class Composer extends React.Component {
  componentWillMount() {
    // some specific behavior of Composer isn't hoisted to wrapper
  }

  render() {
    return <input type="text" ref="input" />
  }

  static someStaticMethod() {

  }

  focus() {
    return this.input.focus()
  }
}

function someDecorator() {
  return function (WrappedComponent) {
    class Wrapper extends Component {
      static displayName = `Wrapper(${WrappedComponent.displayName})`

      componentWillMount() {
        // some specific logic in a decorator, left intact
      }

      render() {
        return <WrappedComponent ref="wrappedComponent" />
      }
    }

    return hoistNonReactMethods(Wrapper, WrappedComponent, {
      delegateTo: c => c.refs.wrappedComponent
    })
  }
}

class Root extends React.Component {
  // works!
  render() {
    return (
      <div>
        <button onClick={e => this.refs.composer.focus()}></button>
        <Composer ref="composer" />
      </div>
    )
  }
}
```

## API

```js
hoistNonReactMethods(
  Wrapper: ReactComponent,
  WrappedComponent: ReactComponent,
  {
    delegateTo: function(ReactComponent wrapperComponentInstance):ReactComponent childComponentInstance,
    hoistStatics: boolean,
  }
)
```

The third parameter is a configuration object. Options:

- `delegateTo`: a function that gets the instance of the wrapper component and returns the instance of the wrapped component (e.g. `wrapper => wrapper.refs.child`)
- `hoistStatics: true/false` - controls whether to hoist statics or not

## Test

```sh
npm install
npm test
```

## License

MIT

---
_Source: https://npm.io/package/hoist-non-react-methods · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
