I am new to Reactjs, I have done a test code to manage different kinds of popups by state, I have a array to hold all popups and stored in state object.
When a popup is displayed, the code will add the popup into the array, and assign an unique handle to it. But when a popup is closed via close button, the popup stored in the array will be removed.
The popup can be displayed via button click, and the array in state is updated correctly. However, when the close button inside the popup is pressed, handleClose callback is called, for some reason, the array was changed to empty which is the initial value.
Could someone kindly help please?
Here is the code:
import React, { useState } from 'react';import './App.css';import "bootstrap/dist/css/bootstrap.min.css";import Notification from './Notifification';import Button from 'react-bootstrap/Button';import Form from 'react-bootstrap/Form';interface componentType { item: React.ReactNode; handle: number;}interface stateType { index: number; unused?: number; array: componentType[];}const App: React.FC = () => { const [state, setstate] = useState<stateType>({ index: 1, array: [] }) const handleClose = (ok: boolean, handle: number) => { const comp = state.array.find(c => c.handle === handle) if (comp === undefined) { //It will run here as the array is empty console.log("Error: not there, handle = " + handle, " array = " + state.array) return } const newArray = state.array.filter((value, index, arr) => { return value.handle !== handle; }) console.log("new array in close popup = ", newArray) setstate({ ...state, array: newArray }) } const showPopup = () => { console.log("show popup"); const idx = state.index + 1 let comp: componentType = { item: <Notification handleClose={handleClose} title={'TEST'} body={'BODY'} handle={idx}></Notification>, handle: idx } const newArray = [...state.array, comp] console.log("new array in show popup = ", newArray) setstate({ ...state, index: idx, array: newArray }) } return (<><Form><Button className="mr-sm-2" onClick={() => showPopup()}>Popup button</Button></Form> { //after the Popup button is clicked, the array should be correct, as the popup can be seen state.array.map((component, index) => { return React.isValidElement(component.item) ? React.cloneElement(component.item, { key: index }) : component.item } )}</> );}export default App;
Notification.tsx
import React from "react";import Modal from "react-bootstrap/Modal";import Button from "react-bootstrap/Button";export interface NotificationProps { handleClose: (ok: boolean, handle: number) => void; title: string; body: string; handle: number;}const Notification: React.FC<NotificationProps> = ({ handleClose, handle, title, body, ...props }) => { return (<Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter" centered show={true}><Modal.Header closeButton><Modal.Title id="contained-modal-title-vcenter"> {title}</Modal.Title></Modal.Header><Modal.Body> {body}</Modal.Body><Modal.Footer><Button onClick={() => { handleClose(true, handle) }} className="mr-sm-2">OK</Button><Button variant="secondary" onClick={() => { handleClose(false, handle) }}>Cancel</Button></Modal.Footer></Modal > );}export default Notification;