0

I have created a function that's a separate React Component called Modal.js file that I would like to call the buttons that going to open Modal another React component - how can I achieve this?

Modal.js

class Modal extends React.Component {
  state = {
    loginOpened: false,
    signupOpened: false
  };

  openModal = modalType => () => {
    if (modalType === "login") {
      this.setState({
        loginOpened: true,
        signupOpened: false
      });
    } else if (modalType === "signup") {
      this.setState({
        loginOpened: false,
        signupOpened: true
      });
    }
  };

  closeModal = modalType => () => {
    if (modalType === "login") {
      this.setState({
        loginOpened: false
      });
    } else if (modalType === "signup") {
      this.setState({
        signupOpened: false
      });
    }
  };

    render() {
      return (
          <>
              <Modal isOpen={loginOpened} onRequestClose={this.closeModal("login")}>
                <h1>Login</h1>
                <button onClick={this.openModal("signup")}>Open Signup</button>
                <button onClick={this.closeModal("login")}>Close this modal</button>
              </Modal>

              <Modal isOpen={signupOpened} onRequestClose={this.closeModal("signup")}>
                <h1>Sign Up</h1>
                <button onClick={this.openModal("login")}>Open Login</button>
                <button onClick={this.closeModal("signup")}>Close this modal</button>
              </Modal>

              <button onClick={this.openModal("login")}>Open Login</button>
              <button onClick={this.openModal("signup")}>Open Signup</button>
          </>
      );
    }
}

  export default Modal;

I want to move this to Navigation.js So when those buttons are clicked the modal window will be called

<button onClick={this.openModal("login")}>Open Login</button>
<button onClick={this.openModal("signup")}>Open Signup</button>
1
  • Can you show us Navigation.js and how its component is related to <Modal> please? Commented Mar 11, 2020 at 17:56

1 Answer 1

1

The easiest way to achieve this is over Context.

The files you should have are:

// ModalContext.js
import {createContext} from 'react'

export default createContext()
// Root.js -> This file should be on top of your application
import React from 'react'
import ModalContext from './ModalContext'

class ModalProvider extends React.Component {
  state = {
    loginOpened: false,
    signupOpened: false
  };

  openModal = modalType => () => {
    if (modalType === "login") {
      this.setState({
        loginOpened: true,
        signupOpened: false
      });
    } else if (modalType === "signup") {
      this.setState({
        loginOpened: false,
        signupOpened: true
      });
    }
  };

  closeModal = modalType => () => {
    if (modalType === "login") {
      this.setState({
        loginOpened: false
      });
    } else if (modalType === "signup") {
      this.setState({
        signupOpened: false
      });
    }
  };

  render(props) {
    return 
      <ModalContext.Provider value={{openModal: this.openModal, closeModal: this.closeModal}}>
        <Modal isOpen={loginOpened} onRequestClose={this.closeModal("login")}>
          <h1>Login</h1>
          <button onClick={this.openModal("signup")}>Open Signup</button>
          <button onClick={this.closeModal("login")}>Close this modal</button>
        </Modal>
        <Modal isOpen={signupOpened} onRequestClose={this.closeModal("signup")}>
           <h1>Sign Up</h1>
           <button onClick={this.openModal("login")}>Open Login</button>
           <button onClick={this.closeModal("signup")}>Close this modal</button>
        </Modal>
        {props.children}
      </ModalContext.Provider>
    )
  }
}

export default
// Anywhere where you need to control your modals
import ModalContext from './ModalContext'

class MyComponent extends React.Component {
  ...
  render(props) {
    return (
      <ModalContext.Consumer>
        {({openModal, closeModal}) => <button onClick={openModal("login")}>Open Login</button>}
      </ModalContext.Consumer>
    )
  }
}

You can check more on Contexts here

Sign up to request clarification or add additional context in comments.

2 Comments

When I read and setup everything way that your teaching me. I'm getting an error message saying that TypeError: render is not a function after adding the 3th code in my navbar.
I updated my response, probably you didn't put the render function on a React Component. I recommend you to check functional components with the use of hooks. That's the new way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.