Search code examples
reactjsreact-modal

How do I import react-modal into existing application?


I've been slowly trying to migrate some pieces of an existing, large php/jquery project to use ReactJS, especially using some reusable components. ReactJS has been working well for me, but today I tried to import a library using npm, which is completely new to me.

After running npm install react-modal I see that node_modules\react-modal (along with several other folders) were created. So far, so good.

However, I cannot seem to include that component into my project. If I try import ReactModal from 'react-modal'; at the top of my component's .js file, I get: Uncaught ReferenceError: require is not defined. I get errors thrown if I try to include the node_modules\react-modal\lib\components\Modal.js file directly, which I realize is probably the wrong approach but I'm grasping at straws here. I suspect I'm missing something basic, but I just can't seem to figure this one out. Does anyone have any ideas?

Edit: here is how I include React into my project currently:

<!-- Load React. -->
{if $env=="prod"}
    <script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>

    {* tabs support *}
    <script src="https://unpkg.com/prop-types/prop-types.js"></script>
    <script src="https://unpkg.com/react-tabs@3/dist/react-tabs.production.min.js"></script>
    <link href="https://unpkg.com/react-tabs@3/style/react-tabs.css" rel="stylesheet"> 

{else}

    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

    {* tabs support *}
    <script src="https://unpkg.com/prop-types/prop-types.js"></script>
    <script src="https://unpkg.com/react-tabs@3/dist/react-tabs.development.js"></script>
    <link href="https://unpkg.com/react-tabs@3/style/react-tabs.css" rel="stylesheet">

{/if}

{* Babel support *}
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

This is the full component (contents of the matchSelector.js file):

import Modal from 'react-modal';

/**
 * Select a match with hooks to return the proper match info to the instantiator
 */
class MatchSelector extends React.Component {
    /**
     * Class Constructor
     * 
     * props expected:
     *      className - (optional) use if you want to style the picker button/icon differently. Note that
     *      if given, all standard classes will be overrided.
     * 
     *      type - (optional) can be "text", "icon", "both". Default is "both".
     * 
     *      text - (optional) if type is "text" or "both", the text to use on the button. Default is "Select Match"
     * 
     */
    constructor(props) {
        super(props);       // let Dad know what's up

        this.state = {showDialog:false}

        this.handleClick = this.handleClick.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }

    handleClick(event) {
        event.preventDefault();

        this.setState({showDialog:true});
    }

    handleClose() {
        this.setState({showDialog:false});
    }

    render() {
        const defaultClassName = "ui-state-default ui-corner-all ui-button compressed";
        let className = (odcmp.empty(this.props.className)?defaultClassName:this.props.className);

        return (
                <React.Fragment>
                    <button 
                        className={className}   
                        onClick={this.handleClick}>
                            {this.buttonContent()}
                    </button>
                    <MatchSearchDialog
                        show={this.state.showDialog} />
                </React.Fragment>
        );
    }

    buttonContent() {
        var text = (odcmp.empty(this.props.text)?"Select Match":this.props.text);

        if (odcmp.empty(this.props.type) || (this.props.type.toLowerCase()=="both")) {
            return (
                <span><span className="ui-icon ui-icon-search inline"></span>{text}</span>
            );
        } else if (this.props.type.toLowerCase()=="icon") {
            return (
                <span className="ui-icon ui-icon-search inline"></span>
            );
        } else {
            return text;
        }
    }
}

class MatchSearchDialog extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <ReactModal isOpen={false}><div>hi</div></ReactModal>
        );
    }
}

Solution

  • In case anyone runs into this, I wanted to add my resolution.

    I was trying to run a bare bones REACTJS project without webpack. react-modal depends on webpack (as does, I'm sure, many React components). As I'm trying to stay light and agile, I removed the react-modal module and "rolled my own" modal dialog.

    FYI, the clue is the "require not defined" error in the console - indicating a non-browser (node.js) function was hit. It was expecting to compile (webpack) into a separate js file using the node.js terminology.