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.
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.
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
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.
We can use the following approach in ReactJS to use the Ant Design Collapse Component. accordion: It is used to collapse renders as Accordion if this value is set to true. activeKey: It is used to denote the key of the active panel.
There are multiple options for expanding and collapsing any header on the basis of varying requirement. By default we get a react accordion component where only one item can be expanded. In order to collapse this accordion, you need to expand another component.
The collapse component is used to show and hide content. Buttons or anchors are used as triggers that are mapped to specific elements you toggle. Collapsing an element will animate the height from its current value to 0.
React Nested Collapse The final example of react collapse component consists of container within a toggle container. That means we can apply collapse action on child container for single collapse action or apply it directly to parent container for collapse all feature.
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.
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.
Code for your reference (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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With