Search code examples
javascriptreactjssemantic-uisetstatesemantic-ui-react

Trying to render a Pop up outside of render: React Js


I am trying to bring popup based on clicking of the respective links. Here I could see onClick is being triggered along with the state change But no modal is appearing.

Can some one tell me what is it that I am doing wrong. I am using semantic-ui-react modal for the same puropse

Sandbox: https://codesandbox.io/s/semantic-ui-example-seg91?file=/Modal.js

import React from "react";
import Modal from "./Modal";

class LoaderExampleText extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isModalOpen: false
    };
  }

  setModal = (e, value) => {
    console.log(value);
    e.stopPropagation();
    this.setState({ isModalOpen: true });
    return (
      <Modal
        modalOpen={this.state.isModalOpen}
        handleClose={() => {
          this.setState({ isModalOpen: false });
        }}
        items={value}
      />
    );
  };
  render() {
    return (
      <>
        <a onClick={e => this.setModal(e, "first item")}>Modal A</a>
        <a onClick={e => this.setModal(e, "second Item")}>Modal B</a>
      </>
    );
  }
}
export default LoaderExampleText;

import * as React from "react";
import { Modal } from "semantic-ui-react";

class NestedTableViewer extends React.Component {
  render() {
    return (
      <>
        <Modal closeIcon={true} open={this.props.modalOpen}>
          <Modal.Header>Modal</Modal.Header>
          <Modal.Content>
            <h1> {this.props.items}</h1>
          </Modal.Content>
        </Modal>
      </>
    );
  }
}

export default NestedTableViewer;


Solution

  • Save the value into state and move the modal into the render return. All renderable JSX needs to be returned as a single node tree.

    import React from "react";
    import Modal from "./Modal";
    
    class LoaderExampleText extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          isModalOpen: false,
          value: null
        };
      }
    
      setModal = (e, value) => {
        console.log(value);
        e.stopPropagation();
        this.setState({ isModalOpen: true, value });
      };
    
      render() {
        return (
          <>
            <a onClick={e => this.setModal(e, "first item")}>Modal A</a>
            <a onClick={e => this.setModal(e, "second Item")}>Modal B</a>
            <Modal
              modalOpen={this.state.isModalOpen}
              handleClose={() => {
                this.setState({ isModalOpen: false, value: null });
              }}
              items={this.state.value}
            />
          </>
        );
      }
    }
    export default LoaderExampleText;
    

    Edit semantic-ui-example