为啥 destroyOnClose=true 在 React 中不起作用

Posted

技术标签:

【中文标题】为啥 destroyOnClose=true 在 React 中不起作用【英文标题】:why destroyOnClose=true not working in React为什么 destroyOnClose=true 在 React 中不起作用 【发布时间】:2020-12-25 20:46:49 【问题描述】:

我正在使用 TypeScript 开发一个基于 React 钩子的功能应用程序,并且我正在使用来自 ant design 的模态。我正在通过模式提交表格的表格。因此,模态框将被多次调用以填充表格的不同行。

问题是,当模态框在第二次、第三次或横向弹出时,它总是带有以前的值。

为了避免这种情况,我在模态中设置了 EnableViewState="false" ,它不起作用。我设置 destroyOnClose=true。它没有用。在modal documentation 中,它是在destroyOnClose 不起作用时编写的,那么我们需要使用 .但是在哪里定义呢?因为,当我设置为, <Form onSubmit=props.inputSubmit preserve=false 在我的模态表单中,我收到一条错误消息 Type ' children: Element[]; onSubmit: any; preserve: boolean; ' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Form>......?

您使用什么来使每次重新加载模态时,它都重新加载为空?我不想在输入的表单值字段中分配状态。是否还有其他选项,例如 destroyOnClose=true ?

这是我的模态,

<Form onSubmit=props.inputSubmit>
  <Row>
    <Col span=10>
      <Form.Item>
        <Text strong=true>Article name: </Text>
      </Form.Item>
    </Col>
    <Col span=12>
      <Form.Item>
        <Input
          style= backgroundColor: '#e6f9ff' 
          name="articleName"
          onChange=props.handleArticleModalInput
        />
      </Form.Item>
    </Col>
  </Row>
</Form>

这里是调用模态的地方,

return (
  <>
    <ArticleTableModal
      destroyOnClose=true
      isVisible=modalVisibilty
      inputSubmit=inputSubmit
      handleCancel=handleCancel
      filledData=fetchedData
      articleNumber=articleNumber
      handleArticleModalInput=handleArticleModalInput

    />

    <Table
      pagination=false
      dataSource=articleDataSource
      columns=articleColumns
      scroll= y: 400 
      bordered
    />
  </>
)

非常感谢任何帮助。

【问题讨论】:

通常情况下,不会每次都创建一个全新的模态对话框窗口。这可能就是你遇到摩擦的原因。建议在父类组件或 useState 钩子(或自定义钩子)中将模态内容保持为状态,并在设置模态时更新该状态。您甚至可以使用卸载逻辑将内容重置为空字符串或其他一些非值。 您好@JaredSmith...感谢您尝试帮助我。但是你可以举个例子吗?每当使用输入数据时,我都会将“模态内容作为父类组件中的状态”,我只是不会再次将该值更新回模态。我认为来回通信会使我的应用程序变得繁重。特别是“您甚至可以使用卸载逻辑将内容重置为空字符串或其他非值”是什么意思? 在下面查看我的答案。 【参考方案1】:

在这里,我们将使用一个自定义钩子来包装来自其他地方(如 3rd 方 UI 库)的 ModalDialog 组件,并返回一个 setter 元组和一个自包含组件/null。 Hooks 让这一切变得更整洁,但您仍然可以使用类组件来完成所有这些工作,但代价是有点冗长。由于您标记了 Typescript,这一切都应该很简单,但您可能必须指定您使用的 useState 是 useState&lt;React.ReactChild&gt;(); 以避免类型错误。

const useDialog = (ModalComponent) => 
  const [modalDialogState, setModalDialogState] = useState();
  return modalDialogState
    ? [
      setModalDialogState,
      // You may have to tweak this a bit depending on
      // how your library works.
      () => (
        <ModalComponent onClose=() => setModalDialogState('')> 
          modalDialogState
        </ModalComponent>
      ),
    ]
    : [setModalDialogState, null];
;

const MyComponent = () => 
  const [setModal, Modal] = useDialog(WhateverLibraryComponent);
  useEffect(() => 
    // Cleanup function, run on unMount and clears dialog contents.
    return () => setModal('');
  , [setModal]);

  return Modal
    ? (
      <>
        <Modal />
        /* Normal render stuff */
      </>
    )
    // You can optionally render a button here with onClick
    // set to a function that calls setModal with some 
    // appropriate contents.
    : (/* Normal render stuff */)
;
    

【讨论】:

【参考方案2】:

您需要在每次模式启动时为表单中的字段生成动态键。

这是一个可以玩的沙盒。如果您不对键进行任何更改,则模式会在其​​中保留值。如果您更改键并启动模式,则该值将被清除。

Sandbox Link

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import  Modal, Button, Input  from "antd";

class App extends React.Component 
  state =  visible: false, theKey: "dummy" ;

  showModal = () => 
    this.setState(
      visible: true
    );
  ;

  handleOk = (e) => 
    console.log(e);
    this.setState(
      visible: false
    );
  ;

  handleCancel = (e) => 
    console.log(e);
    this.setState(
      visible: false
    );
  ;

  handleChange = ( target:  value  ) => 
    this.setState( theKey: value );
  ;

  render() 
    return (
      <>
        <Input onChange=this.handleChange placeholder="key for input field"/>
        <br />
        <Button type="primary" onClick=this.showModal>
          Open Modal
        </Button>
        <Modal
          title="Basic Modal"
          visible=this.state.visible
          onOk=this.handleOk
          onCancel=this.handleCancel
        >
          <Input
            key=this.state.theKey
            style= backgroundColor: "#e6f9ff" 
            name="articleName"
          />
        </Modal>
      </>
    );
  


ReactDOM.render(<App />, document.getElementById("container"));

【讨论】:

Hello @MjZac ..... 使用动态键并通过状态处理更改它的解决方案确实有帮助。我将对此发表回复。对我来说,清空通过的状态并没有帮助,但这个关键处理就像魅力一样。我什至使用了自定义模式的键,并从我的其他组件中调用它......非常感谢! 但是用这个实现不是有内存泄漏的机会吗?

以上是关于为啥 destroyOnClose=true 在 React 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 "true" == true 在 JavaScript 中显示为 false?

为啥“[False, True] 中的 not(True)”返回 False?

为啥“draggable = 'true'”不能在 React 渲染组件上工作?

为啥下面的表达式返回 true?

为啥在 Hibernate 中不推荐“hibernate.connection.autocommit = true”?

为啥 Request.IsSecureConnection 在预期为 true 时返回 false