Reputation: 6896
I have a <Panel/>
component that has to get different changing components.
For example one time- the <Panel/>
needs to contain a <Dropdown/>
component, a second time a <TextInput/>
and in the third time a <Checkbox/>
.
How can I make this <Panel/>
component to get different components?
The <Panel/>
component:
import React from "react";
import { css } from "emotion";
import colors from '../../styles/colors';
import PanelHeader from "./PanelHeader";
export default function Panel({ active, panelHeader}) {
const styles = css({
borderRadius: 4,
backgroundColor: "white",
border: `1px solid ${ active ? colors.blue : colors.grayLight }`,
width: 540,
padding: 32,
});
return (
<div className={styles}>
{panelHeader && <PanelHeader headerType={panelHeader} />}
</div>
);
}
The Panel story:
import React from "react";
import { storiesOf } from "@storybook/react";
import Panel from "../components/Panel";
import colors from '../styles/colors';
import PanelHeader from "../components/Panel/PanelHeader";
storiesOf("Panel", module)
.add("Default", () => (
<Panel></Panel>
))
.add("Active", () => (
<Panel active></Panel>
))
storiesOf("Panel/PanelHeader", module)
.add("Default", () => (
<PanelHeader headerType="Identity document" color={colors.gray}>1</PanelHeader>
))
.add("Active", () => (
<PanelHeader headerType="Identity document" color={colors.blue}>1</PanelHeader>
))
Upvotes: 0
Views: 39
Reputation: 8217
You can change Panel
to accept children
prop, pass it where you Render <Panel>
and pass in the corresponding component.
For example:
// PropType for children is `PropTypes.node`
export default function Panel({ active, panelHeader, children}) {
// ...
return (
<div className={styles}>
{children}
</div>
);
}
// ...
<Panel><Dropdown /></Panel>
// or
<Panel><TextInput /></Panel>
Or, you could pass in a component class/function and render it inside:
export default function Panel({ active, panelHeader, ChildComponent}) {
// ...
return (
<div className={styles}>
{/* This is like any other component,
you can pass in props as usual. */}
{/* It's important for the name to start with an uppercase letter,
otherwise the JSX compiler will turn this in a string! */}
<ChildComponent />
</div>
);
}
// ...
<Panel ChildComponent={Dropdown}></Panel>
// or
<Panel ChildComponent={TextInput}></Panel>
This pattern is called component composition. You can read more in React docs: https://reactjs.org/docs/composition-vs-inheritance.html
Upvotes: 1