简体   繁体   English

动态打开和关闭 antd/react 折叠组件

[英]Dynamically Open and Close antd / react Collapse Component

I want to dynamically open/close Collapse Elements independent of user interaction (to reveal a specific panel via a search result).我想独立于用户交互动态打开/关闭折叠元素(通过搜索结果显示特定面板)。

The Collapse react component has setActiveKey (and uses it on user click) but it is not exposed to the Collapse Node reference. Collapse react 组件有 setActiveKey(并在用户点击时使用它),但它没有暴露给 Collapse Node 引用。

Is there anyway to open or close in a way that will not trigger a re-render?无论如何以不会触发重新渲染的方式打开或关闭?

I tried using state and props, but this always re-renders the full tree of nested Collapse components, which in my case takes over 3 seconds.我尝试使用 state 和 props,但这总是重新渲染嵌套的 Collapse 组件的完整树,在我的情况下需要超过 3 秒。

Posting the full code would be excessive here as there are many interdependent components nested.由于嵌套了许多相互依赖的组件,因此在此处发布完整代码会过多。 However the basic structure is visible here: https://codesandbox.io/s/nk64q4xy8p但是基本结构在这里可见: https : //codesandbox.io/s/nk64q4xy8p

I want to open a specific panel via a different user interaction.我想通过不同的用户交互打开一个特定的面板。 In the codepen that would be onChange of the select or clicking the button.在选择或单击按钮的 onChange 的代码笔中。

There is nothing bad to do it with state variable.用状态变量做这件事没什么不好。 Once state or props change, it will render the entire components and also the nexted ones.一旦 state 或 props 发生变化,它将渲染整个组件以及下一个组件。

But if there is any performance issue due to re-rendering, probably you should look into pure components and react lifecycle methods to improve the performance (or avoid re-render).但是,如果由于重新渲染而出现任何性能问题,您可能应该查看纯组件并响应生命周期方法以提高性能(或避免重新渲染)。

In addition, you can also use special props of Antd's Collapse destroyInactivePanel , it will destroy (unmount) inactive panels.此外,您还可以使用 Antd 的 Collapse destroyInactivePanel 的特殊道具,它会销毁(卸载)非活动面板。

Code for your reference ( https://codesandbox.io/s/y30z35p1vv?fontsize=14 )代码供您参考( https://codesandbox.io/s/y30z35p1vv?fontsize=14

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Collapse, Button, Select } from "antd";

const Panel = Collapse.Panel;
const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

class AvoidRenders extends React.Component {
  state = {
    openPanel: "1"
  };

  onChange = key => {
    this.setState({
      openPanel: key
    });
  };

  render = () => {
    return (
      <div>
        <Select
          dropdownMatchSelectWidth={false}
          defaultValue="1"
          onChange={this.onChange}
        >
          <Select.Option key="1" value="1">
            Panel 1
          </Select.Option>
          <Select.Option key="2" value="2">
            Panel 2
          </Select.Option>
          <Select.Option key="3" value="3">
            Panel 3
          </Select.Option>
        </Select>
        <Collapse activeKey={this.state.openPanel} destroyInactivePanel={true}>
          <Panel header="This is panel header 1" key="1">
            <Text1 />
          </Panel>
          <Panel header="This is panel header 2" key="2">
            <Text2 />
          </Panel>
          <Panel header="This is panel header 3" key="3">
            <Text3 />
          </Panel>
        </Collapse>
      </div>
    );
  };
}

class Text1 extends React.PureComponent {
  componentWillUnmount = () => {
    console.log("Destroyed 1");
  };
  componentWillUpdate = () => {
    console.log("Updated 1");
  };
  render = () => (
    <p>
      {console.log("Rendered 1")}
      {text}
    </p>
  );
}

class Text2 extends React.PureComponent {
  componentWillUnmount = () => {
    console.log("Destroyed 2");
  };
  componentWillUpdate = () => {
    console.log("Updated 2");
  };
  render = () => (
    <p>
      {console.log("Rendered 2")}
      {text}
    </p>
  );
}

class Text3 extends React.PureComponent {
  componentWillUnmount = () => {
    console.log("Destroyed 3");
  };
  componentWillUpdate = () => {
    console.log("Updated 3");
  };
  render = () => (
    <p>
      {console.log("Rendered 3")}
      {text}
    </p>
  );
}

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

I hope, this would help.我希望,这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM