How to pass data from the first element to the second one by clicking the button?
If we open the second component by clicking on the panel, it must to stay empty.
It is welcomed if the answer is with items
, and not with Collapse.Panel
.
Also, I had to hardcode the activeKey
value which is completely
wrong and immobilizes the entire parent Collapse component.
interface ChildComponentProps {
//activeKey: number;
//setActiveKey: React.Dispatch<React.SetStateAction<string>>;
setActiveKey: (newType: string) => void;
}
const Element1: React.FC<ChildComponentProps> = ({ setActiveKey }) => {
// need to pass this 'car'
const car: { type: string, model: string, year: number } = {
type: "Toyota",
model: "Corolla",
year: 2009
};
const handleClick = (key: string) => {
setActiveKey(key);
}
return (
<div>
<div>
<Button
onClick={() => handleClick('2')} // wrong hardcoding!
>expandNextPanel
</Button>
</div>
</div>
);
}
const Element2 = () => {
return (
<div>
<div>
go back to the first component and click the button
</div>
</div>
);
}
const CollapseComponent = () => {
const [activeKey, setActiveKey] = useState<string>();
return (
<Collapse
activeKey={activeKey}
onChange={() => setActiveKey(activeKey)}
>
<Collapse.Panel header="Element1" key="1">
<Element1
setActiveKey={setActiveKey}
/>
</Collapse.Panel>
<Collapse.Panel header="Element2" key="2">
<Element2 />
</Collapse.Panel>
</Collapse>
);
}
export default CollapseComponent;
To pass data from one Collapse.Panel
(like Element1
) to another (Element2
) only when a button is clicked, and not when the panel is opened manually, you can use shared state at the parent level (CollapseComponent
) and conditionally inject props only when the transition is triggered programmatically.
You should also avoid hardcoding activeKey
. Instead, update it dynamically based on interaction.
Here’s a working approach using Ant Design Collapse, React, and TypeScript:
Manage activeKey
in parent via useState
.
Store car
data in parent temporarily when "Next" is clicked.
Only pass car
to Element2
when the transition is user-triggered (not manually expanded).
Use items
instead of <Collapse.Panel>
.
import React, { useState } from 'react';
import { Collapse, Button } from 'antd';
import type { CollapseProps } from 'antd';
interface Car {
type: string;
model: string;
year: number;
}
interface Element1Props {
onNext: (car: Car) => void;
}
const Element1: React.FC<Element1Props> = ({ onNext }) => {
const car: Car = {
type: "Toyota",
model: "Corolla",
year: 2009
};
return (
<div>
<Button onClick={() => onNext(car)}>Expand Next Panel</Button>
</div>
);
};
interface Element2Props {
car?: Car;
}
const Element2: React.FC<Element2Props> = ({ car }) => {
if (!car) {
return <div>Go back to the first component and click the button</div>;
}
return (
<div>
<div><strong>Car Type:</strong> {car.type}</div>
<div><strong>Model:</strong> {car.model}</div>
<div><strong>Year:</strong> {car.year}</div>
</div>
);
};
const CollapseComponent: React.FC = () => {
const [activeKey, setActiveKey] = useState<string | string[]>();
const [sharedCar, setSharedCar] = useState<Car | undefined>(undefined);
const handleNext = (car: Car) => {
setSharedCar(car);
setActiveKey("2");
};
const items: CollapseProps['items'] = [
{
key: '1',
label: 'Element1',
children: <Element1 onNext={handleNext} />
},
{
key: '2',
label: 'Element2',
children: <Element2 car={sharedCar} />
}
];
const handleChange = (key: string | string[]) => {
setActiveKey(key);
// Optional: clear car data if user manually opens panel 2
if (key !== '2') {
setSharedCar(undefined);
}
};
return (
<Collapse activeKey={activeKey} onChange={handleChange} items={items} />
);
};
export default CollapseComponent;
This uses the items
API from Ant Design Collapse.
sharedCar
only gets passed when onNext
is used.
If the user manually opens the second panel, it remains empty (as requested).