Search code examples
javascriptreactjsecmascript-6grommet

React calling another component


I am using Grommet and am trying to get Layer (pretty much a modal) to work when a button is pressed. I know that my onClick works because I tried a simple console.log and it works. MyModal is also able to be displayed if I use ReactDOM and render it. I think my problem has something to do with how I am calling it or returning it? I want the modal to display when the button is clicked.

MyModal.js

import React, { Component } from 'react';
import Layer from 'grommet/components/Layer';
import Header  from 'grommet/components/Header';
import Heading from 'grommet/components/Heading';
import Section from 'grommet/components/Section';
import Paragraph from 'grommet/components/Paragraph';

export default class MyModal extends Component {  
  render () {
    return (
        <Layer closer={true} align="top">
            <Header>
                <Heading tag="h2">
                    Title
                </Heading>
            </Header>
            <Section>
                <Paragraph>
                    This is a simple dialog.
                </Paragraph>
            </Section>
        </Layer>
    );
  }
};

Main.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from 'grommet/components/App';
import Button from 'grommet/components/Button';
import MyModal from './components/MyModal';

export default class Main extends Component {
  getComponent(event) {
    return <MyModal/>;
  }
  render () {
    return (
      <App centered={false}>
           <Button onClick={this.getComponent.bind(this)} label="Action" />
      </App>
    );
  }
};

Solution

  • THE ISSUE:
    You are trying to render your Modal into an in-line onClick handler.

    SUGGESTED SOLUTION:

    • set a value in state to handle when the modal is shown

    • set the onClick to toggle this value

    • use this state to call another method in render to conditionally render the Modal

    What your code could be amended to:

    export default class Main extends Component {
      constructor(props) {
        super(props);
        this.state = {
            showModal: false  // set a value in state to store whether or
                              // not to show the Modal
        };
    
        // I've just put these binding in the constructor 
        // so as not to clock up the render method and they only
        // get called once during the lifetime of the component
        this.handleClick = this.handleClick.bind(this);
      }
      handleClick(event) {  // switch the value of the showModal state
        this.setState({
          showModal: !this.state.showModal
        });
      }
      getComponent() {
        if (this.state.showModal) {  // show the modal if state showModal is true
          return <MyModal/>;
        } else {
          return null;
        }
      }
      render() {
        return (
          <App centered={false}>
            <Button onClick={this.handleClick} label="Action"/>
    {this.getComponent} // call the method to render the modal here. </App> ); } };
    /