Reputation: 97
I´ve got this code snippet:
export const MessageWindow: FunctionComponent<MessageWindowProps> = ({ children, buttonsType }) => {
return (
<div className={classNames()}>
<div className={messageWindowContent}>
{children}
</div>
<div className={messageWindowButtons}>
{buttonsType === "yesno" ?
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="No" title="No" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Yes" title="Yes" />
</> : buttonsType === "saveclose" ?
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Save" title="Save" />
</> : buttonsType === "close" ?
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />
</> : null
}
</div>
</div>
);
}
where "buttonsType" is those enums:
export enum ButtonsType {
yesno = "yesno",
saveclose = "saveclose",
close = "close"
}
I´d like to know some better way, to simplify the conditional statement. Or is it possible to have it like this?
Thank you.
Upvotes: 0
Views: 101
Reputation: 3519
I think Ray Hatfield's answer is the cleanest solution and avoids repetitive JSX, but I'll add a switch example as an option. Ternary generally seems like a poor option for this case.
let buttons;
switch (buttonsType) {
case 'yesno':
buttons =
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="No" title="No" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Yes" title="Yes" />
</>;
break;
case 'saveclose':
buttons =
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Save" title="Save" />
</>;
break;
case 'close':
buttons =
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />;
break;
default:
buttons = null;
}
return (
<div className={classNames()}>
<div className={messageWindowContent}>
{children}
</div>
<div className={messageWindowButtons}>
{buttons}
</div>
</div>
);
Upvotes: 0
Reputation: 27285
You could create a mapping of types to button configuration objects:
const buttons = {
yesno: [
{ title: 'No', action: () => { /* do stuff */} },
{ title: 'Yes', action: () => { /* do stuff */} },
],
saveclose: [
{ title: 'Save', action: () => { } },
{ title: 'Close', action: () => { } },
],
// etc.
}
And then render buttons according to the configs for the associated type:
buttons[buttonsType].map(({title, action}) => (
<Button
key={title}
color={TextColor.colorPrimary}
text={title}
title={title}
onClick={action}
/>
));
You could make this its own component and just pass in the types prop:
<MessageWindowButtons buttonTypes={buttonTypes} />
Upvotes: 1
Reputation: 2446
I would factor the button into a different component.
export const TheButton = ({ buttonText, callback }) => {
return <TextButton text={buttonText} title={buttonText} onClick={callback} />;
};
export const TheButtons = ({ buttonsType }) => {
const foo = () => {
/*whatever*/
};
switch (buttonsType) {
case "yesno":
return (
<>
<TextButton buttonText="yes" callback={foo} />
<TextButton buttonText="no" callback={foo} />
</>
);
case "saveclose":
return (
<>
<TextButton buttonText="save" callback={foo} />
<TextButton buttonText="close" callback={foo} />
</>
);
case "close":
return (
<>
<TextButton buttonText="close" callback={foo} />
</>
);
default:
return null;
}
};
export const MessageWindow: FunctionComponent<MessageWindowProps> = ({
children,
buttonsType,
}) => {
return (
<div className={classNames()}>
{" "}
<div className={messageWindowContent}> {children} </div>{" "}
<div className={messageWindowButtons}>
{" "}
<TheButtons buttonsType={buttonsType} />
</div>{" "}
</div>
);
};
Upvotes: 0
Reputation: 1887
{(buttonsType === "yesno" &&
<SomeContent/>)
|| (buttonsType === "saveclose" &&
<SomeOtherContent />)
|| (buttonsType === "close" &&
<YetSomeOtherContent />)
||
<SomeDefaultContent />
}
You can try this; This is almost switch like but in jsx render function directly
Upvotes: 0
Reputation: 2044
<div className={classNames()}>
<div className={messageWindowContent}>
{children}
</div>
<div className={messageWindowButtons}>
{{
yesno:
(
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="No" title="No" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Yes" title="Yes" />
</>
),
saveclose:
(
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Save" title="Save" />
</>
),
close:
(
<>
<TextButton color={TextColor.colorPrimary} onClick={function foo() { }} text="Close" title="Close" />
</>
),
}[buttonType]}
</div>
</div>
This should work, nesting ternary is fine but affects readability.
Upvotes: 0
Reputation: 502
What you can do is separate the jsx for each condition like this:-
{ButtonsType === "yesno" && (<div>( your html )</div>)}
{ButtonsType === "saveclose" && (<div>( your html )</div>)}
Upvotes: 0