Building a Modal component in React without nesting it inside caller component

て烟熏妆下的殇ゞ 提交于 2021-02-10 14:33:51

问题


I'm trying to call a Modal from non-related component (without using any parent-child relationship).

In order to do that I'm trying to use React Redux (as the only way I've seen that can make a connection between two unrelated components). An example on CodeSandbox shows the bare minimum of what I'm trying to do.

My issue is that I don't want to include <Modal> inside the <Button> render function. I want to be able to simply flip the flag in Button.js and <Modal> would appear. This is, from what I understand, is suppose to be one of the advantages of Redux.

It may be look unimportant, but besides the fact that I understand that this is something that can be done and so I want to know how, it will be useful for me in a different piece of code in which if I include <Modal> in the component's render function it'll render the Modal multiple times (I render that component in a list).

Edit:

Just to be clear (as per the example on CodeSandbox), I'm using React classes and not functional components; so no hooks like useDispatch but rather functions like mapDispatchToProps are the way I want to go here.


回答1:


I will Recommend using React Portal, this will inject it inside the given node, I found it to be the best solution for creating modals. I used same in dailylivedeals.com as a POC

import ReactDOM from "react-dom";

render() { 
    return ReactDOM.createPortal(
    this.props.children,
    Document.body
  );
}

This is the simplest and cleanest using React's own feature.

Advantage:

  1. Cleaner and simpler
  2. Each modal instance can have its own modal
  3. Multiple modals can be opened ( even from inside a modal)
  4. Modal target can be dynamic (like modal inside modal)
  5. Multiple modal can be controlled using code easily.

Update :

Eloborate code for modal

import React, {useEffect, useState} from "react";
import ReactDOM from "react-dom";
import {Link} from 'react-router-dom';

import "./modal.scss";

let Modal = ({visible, id, hideModal, children, ...props}) => {

    let [show, setShow] = useState(false);

    useEffect(() => {
        setShow(visible);
        console.log(visible);
    }, [visible]);

    let toggleVisibility = () => {
        //hideModal();
        setShow(!show);
    }

    useEffect(() => {
        if (!show) {
            hideModal();
        }
    }, [show]);


    return <div className="modal-scratchpad">
        {show ?
            ReactDOM.createPortal(
                <div id={`${id}-modal-wrapper`} className="sample-modal-wrapper">
                    <div id={`${id}-modal-backdrop`} className="sample-modal-backdrop">
                    </div>
                    <div id={`${id}-modal-container`} className="sample-modal-container">
                        <div id={`${id}-modal`} className="sample-modal">
                            {children}
                            <div onClick={toggleVisibility} className="sample-modal-cross-button">{'\u2716'}</div>
                        </div>
                        <style type="text/css">
                            {"body {" +
                            "overflow:hidden" +
                            "}"}
                        </style>
                    </div>
                </div>
                , document.body)
            : <></>
        }
    </div>

};

export default Modal;


来源:https://stackoverflow.com/questions/65810764/building-a-modal-component-in-react-without-nesting-it-inside-caller-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!