簡體   English   中英

如何簡化此 JSX 條件代碼?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM