【问题标题】: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...感谢您尝试帮助我。但是你可以举个例子吗?每当使用输入数据时,我都会将“模态内容作为父类组件中的状态”,我只是不会再次将该值更新回模态。我认为来回通信会使我的应用程序变得繁重。特别是“您甚至可以使用卸载逻辑将内容重置为空字符串或其他非值”是什么意思?
  • 在下面查看我的答案。

标签: reactjs typescript react-hooks antd ant-design-pro


【解决方案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 ..... 使用动态键并通过状态处理更改它的解决方案确实有帮助。我将对此发表回复。对我来说,清空通过的状态并没有帮助,但这个关键处理就像魅力一样。我什至使用了自定义模式的键,并从我的其他组件中调用它......非常感谢!
    • 但是用这个实现不是有内存泄漏的机会吗?
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 2011-02-27
    • 2015-09-12
    • 2010-10-14
    • 2020-07-15
    • 1970-01-01
    • 2022-07-06
    • 2021-03-18
    相关资源
    最近更新 更多