React Portals provide a great solution for pop-up layer components (see also Protal here). What if there is no Portal for the pop-up layer, such as React Native?
React Native allows the use of Modal components, but is often criticized for hierarchy issues and compatibility with other components.
Let’s solve this problem.
Winding path leading to a secluded spot
The essence of Modal is a view with a higher display level in the component tree, which can cover the entire page, has background color and transparency, and the masked background contains pop-up display area, such as a prompt, dialog box and so on.
Distinguish Modal and content in the mask layer, make the combined mode of father and son components, customize and expose the method of displaying sub-components, and display the sub-component in Modal as a whole, so as to achieve the effect of popup content, and then provide a method to close Modal, which is used to set the hiding of Modal compulsively.
That is, our component satisfies these conditions:
- Higher display levels
- Methods are used to fill in child components and expose show and hide
Modal
The method of
Realization and effect
The command calls will no doubt need to use Ref.
-
Define components. Contains two states, a View and a flag that controls display and hiding. Two methods are exposed, show and close. The view that needs to be displayed is passed in as a method parameter.
import React, { useImperativeHandle, useState } from "react"; function Modal(props, ref) { const [view, setView] = useState([]); const [isShow, setIsShow] = useState(0); useImperativeHandle(ref, () = > ({ init: (view) = > { setView(view); setIsShow(true); }, close: () = > setIsShow(false),}));if (isShow) { return <div style={sts.wrap}>{view}</div>; } else { return null; }}export default React.forwardRef(Modal); export const modalRef = React.createRef(); export const TopModal = { show, close }; function show(view) { modalRef.current.init(view); } function close() { modalRef.current.close(); } / / the layer style const sts = { wrap: { zIndex: 100.top: 0.left: 0.width: "100%".height: "100%".position: "absolute".backgroundColor: "Rgba (0,0,0,0.6)".display: "flex".justifyContent: "center".alignItems: "center",}};Copy the code
-
Place the component higher up the component tree, in this case directly at the same level as App, and pass in the defined Ref.
import Modal, { modalRef } from "./refmodal/component"; ReactDOM.render( <React.StrictMode> <App /> <Modal ref={modalRef} /> </React.StrictMode>.document.getElementById("root"));Copy the code
-
Test the performance.
export default function ModalRefTest() { function openModal() { const view = ( <div style={{ width: 100.height: 100.backgroundColor: "#FFF}} "> <button onClick={close}>Shut down</button> </div> ); TopModal.show(view); } function close() { TopModal.close(); } return ( <div> <button onClick={openModal}>Open the</button> </div> ); } Copy the code
The content of the popup is very simple, just a button that turns off the current Modal, show method and passes in the entire div of the content area.
Effect:
So here, a simplified version of Modal already has an initial effect.
The direction
Make the content to be displayed as a component and pass the component View directly into Modal for display. In this way, you can make dialog boxes, toasts, all kinds of tips. This may also require changes to the background color, which can also be passed to the component as function arguments.
You can also pass in key layout attributes that determine whether the content area should appear in the middle, top, or bottom. From this you can extend the actionSheet component.
You can design the API in the form of show(View,config), read the contents of config, and dynamically set the style and layout display.
React adds a high level view display, which works well with React Native.