简体   繁体   中英

React hook: How to call Modal component from another component in react

I am trying to create a modal that I can reuse/call from multiple components. I want the modal to display in app.js but the button call is on another component.

Once I am able to implement one, I can but button on other components and call same modal instead of having to create the same modal for each component

<div className="App">
      <HeroSlider />
      <HowItWorks />
      <Modal />
      <Footer />
    </div>

The modal button is on this component(HeroSlider). Once its click it will call the modal component and display it in app.js

import React, { useState } from "react";
import Header from './Header'

function HeroSlider(props) {
    const [show, setShow] = useState(false);
    const modalShow = () => setShow(true);
    const openIsAccount = () => {

    }
    return (

 <div className="jumbotron" id="jumbotron2" >
<button type="button" className="btn btn-primary" id="shoutBtn" onClick={modalShow}><span>Get Started</span>
</button>
 </div>
    );
}

export default HeroSlider;

Here is the Modal.js

const IsAccountOpen = (props) => {
    const [show, setShow] = useState(false);
    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);

    return (
        <>
            <Modal show={props.show} onHide={handleClose} backdrop="static" keyboard={false}>
                <Modal.Header closeButton>
                    <Modal.Title>Modal title</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    I will not close 
                 </Modal.Body>
            </Modal>
        </>
    );

};

export default IsAccountOpen

You'll need to extract the state to App level, so that this can be shared to components. You can do this with useState, or using context & custom hooks if you want to make it very clean. But do it with useState on first.

HeroSlider should receive modalShow function in it's props. Modal.js should receive the show state as props.

You need to add a function in the app.js to handle the click on the button, so the function will change the state show to true, and you will pass the state to your modal, like this:

App.js

[showState, setShowState] = useState(false)
buttonClickedHandler = () => {
   setShowState((showState) => showState = !showState )
}

<div className="App">
      <HeroSlider buttonClicked={buttonClickedHandler} />
      <HowItWorks />
      <Modal show={showState} buttonClicked={buttonClickedHandler} />
      <Footer />
</div>

HeroSlider.js

import React, { useState } from "react";
import Header from './Header'

function HeroSlider(props) {
    const [show, setShow] = useState(false);
    const modalShow = () => setShow(true);
    const openIsAccount = () => {

    }
    return (

 <div className="jumbotron" id="jumbotron2" >
<button type="button" className="btn btn-primary" id="shoutBtn" onClick={props.buttonClicked}><span>Get Started</span>
</button>
 </div>
    );
}

export default HeroSlider;

IsAccountOpen.js

const IsAccountOpen = (props) => {
    const [show, setShow] = useState(false);
    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);

    return (
        <>
            <Modal show={props.show} onHide={props.buttonClicked} backdrop="static" keyboard={false}>
                <Modal.Header closeButton>
                    <Modal.Title>Modal title</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    I will not close 
                 </Modal.Body>
            </Modal>
        </>
    );

};

export default IsAccountOpen

I think the best solution is to use redux , because you will need to access and update the state from different components, you shouldn't use context API because the state changes frequently and you will hit the performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM