Skip to content

Higher order component for detecting when a click event has occured outside of a given component

License

Notifications You must be signed in to change notification settings

viralganatra/react-clickoutside

Repository files navigation

React Click Outside

build status npm version

This is a higher order component for detecting when a click event has occured outside of a given component.

It supports both class based components and stateless functional components.

Demo

https://viralganatra.github.io/demos/react-clickoutside/

Installation

Using yarn

yarn add react-clickoutside

or NPM

npm install --save react-clickoutside

New in Version 2

In addition to the existing higher order component, this library now exports a new component, built using the 'function as child component' pattern.

See: https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9

The higher order component now accepts a params object, meaning any properties can be added to the container div.

Introduced Rollup to export two packages; one for Common JS and one for ESM Modules.

How to use

Basic functionality

Using the Function as Child Component approach

import React from 'react';
import { ClickOutside } from 'react-clickoutside';

const MyComponent = () => (
    <div>
        <p>My Component</p>
        <ClickOutside>
            {({ hasClickedOutside }) => (
                <div>
                    <p>Click Outside</p>
                    {hasClickedOutside && <div>Has Clicked Outside</div>}
                </div>
            )}
        </ClickOutside>
    </div>
);

export default MyComponent;

Using the Higher Order Component

import React, { Component } from 'react';
import { withClickOutside } from 'react-clickoutside';
import MyComponent from './my-component';

const ComposedComponent = withClickOutside()(MyComponent);

export default class Demo extends Component {
    onClickOutside = () => {
        // Do something...
    }

    render() {
        return (
            <ComposedComponent
                onClickOutside={this.onClickOutside}
            />
        );
    }
}

The composed component must have the attribute onClickOutside which should be a function.

Customising

The Component will add a wrapping div element to your component. You can add any attributes to this:

Using the Function as Child Component component

const MyComponent = () => (
    <div>
        <p>My Component</p>
        <ClickOutside className="my-class">
            {({ hasClickedOutside }) => (

            )}
        </ClickOutside>
    </div>
);

Using the Higher Order Component

import React, { Component } from 'react';
import { withClickOutside } from 'react-clickoutside';
import MyComponent from './my-component';

const ComposedComponent = withClickOutside({
    className: 'my-class',
})(MyComponent);

Notes

Both components will add a wrapping div element to your component. This is because internally we need to obtain a reference to the container DOM node and use that to calculate if the clicked target node is a child of the container. The problem is that while we can obtain a reference to the node using the ref attribute when the decorated component exposes a regular HTML element, when the ref attribute is used on a custom component the ref callback receives the mounted instance of the component.

https://facebook.github.io/react/docs/refs-and-the-dom.html

In addition using findDOMNode is now discouraged and the React team has plans to deprecate it:

jsx-eslint/eslint-plugin-react#678

Compatibility

React v15 or v16 is a peer dependency.

License

MIT

About

Higher order component for detecting when a click event has occured outside of a given component

Resources

License

Stars

Watchers

Forks

Packages

No packages published