首页 > 解决方案 > setstate 没有更新对象的状态包含反应 js 中的数组成员

问题描述

我是 Reactjs 的新手,我做了一个测试代码来按状态管理不同类型的弹出窗口,我有一个数组来保存所有弹出窗口并存储在状态对象中。

当显示弹出窗口时,代码会将弹出窗口添加到数组中,并为其分配一个唯一句柄。但是当通过关闭按钮关闭弹出窗口时,存储在数组中的弹出窗口将被删除。

可以通过单击按钮显示弹出窗口,并且正确更新状态数组。但是,当按下弹出窗口内的关闭按钮时,会调用 handleClose 回调,由于某种原因,数组被更改为空,这是初始值。

有人可以帮忙吗?

这是代码:

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;

通知.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;

标签: reactjstypescriptreact-native

解决方案



推荐阅读