[英]How Can I Simplify This JSX Conditional Code?
我有這個代碼片段:
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>
);
}
其中“buttonsType”是那些枚舉:
export enum ButtonsType {
yesno = "yesno",
saveclose = "saveclose",
close = "close"
}
我想知道一些更好的方法來簡化條件語句。 或者有可能像這樣嗎?
謝謝你。
您可以創建類型到按鈕配置對象的映射:
const buttons = {
yesno: [
{ title: 'No', action: () => { /* do stuff */} },
{ title: 'Yes', action: () => { /* do stuff */} },
],
saveclose: [
{ title: 'Save', action: () => { } },
{ title: 'Close', action: () => { } },
],
// etc.
}
然后根據關聯類型的配置渲染按鈕:
buttons[buttonsType].map(({title, action}) => (
<Button
key={title}
color={TextColor.colorPrimary}
text={title}
title={title}
onClick={action}
/>
));
您可以將其作為自己的組件,然后傳入 types 屬性:
<MessageWindowButtons buttonTypes={buttonTypes} />
您可以做的是為每個條件分離 jsx,如下所示:-
{ButtonsType === "yesno" && (<div>( your html )</div>)}
{ButtonsType === "saveclose" && (<div>( your html )</div>)}
<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>
這應該有效,嵌套三元很好,但會影響可讀性。
{(buttonsType === "yesno" &&
<SomeContent/>)
|| (buttonsType === "saveclose" &&
<SomeOtherContent />)
|| (buttonsType === "close" &&
<YetSomeOtherContent />)
||
<SomeDefaultContent />
}
你可以試試這個; 這幾乎就像 switch 一樣,但是直接在 jsx 渲染函數中
我認為 Ray Hatfield 的答案是最干凈的解決方案,避免了重復的 JSX,但我會添加一個 switch 示例作為選項。 對於這種情況,三元通常似乎是一個糟糕的選擇。
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>
);
我會將按鈕分解為不同的組件。
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>
);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.