我們在應用程式中隨處使用條件,無論是用於狀態檢查還是根據某些參數將某些資料渲染到視圖中。在這篇文章中將展示一些如何以不同於使用常規 if(...) else {} 區塊甚至使用三元條件的方式呈現條件

例如(1)


type UserType = "admin" | "editor" | "user"

type User = { name : string ;  type : UserType }

const users : User[] = [
    {name : "john", type : "admin"},
    {name : "mike" , type : "editor"},
    {name : "abdelrahman" , type : "user"},
]

export default function Test() {

    const actions = ["create", "read", "update", "delete"]

    return (
        <div>
            {
                users.map(user =>{
                    return <div key={user.name} >
                            {/* we need to render actions depending on user type */}
                            <p>{user.name}</p>
                            <div className='flex items-center'>
                                user actions : 
                                { 
                                    user.type === "admin" && actions.map(a => <Action a={a} key={a} /> ) 
                                }
                                {
                                    user.type === "editor" && actions.filter(a => a !== "create").map(a => <Action a={a} key={a} />)
                                }
                                {
                                    user.type === "user" && actions.filter(a => a !== "create" && a !== "update" && a !== "delete").map(a => <Action a={a} key={a} />) 
                                }
                            </div>
                    </div>
                })
            }

        </div>
    )
}

function Action(props : {a : string}) {
  const {a} = props
  return (
    <p className='px-2  py-1  border-[1px] mx-2 rounded-md'  >{a}</p>
  )
}

輸出例如 (1)

使用常規方法渲染

在這個例子中,我們必須為每個使用者類型建立一個檢查條件來呈現他的操作,正如你所看到的,這會消耗大量程式碼,更難除錯,更難在將來加入更多程式碼,最後看起來很難看,但這是一個更好的方法可以這樣做

範例(2)

type UserType = "admin" | "editor" | "user"

type User = { name : string ;  type : UserType }

const users : User[] = [
    {name : "john", type : "admin"},
    {name : "mike" , type : "editor"},
    {name : "abdelrahman" , type : "user"},
]

const userActionsStates : Record<UserType , string[] > = {
    admin: ["create", "read", "update", "delete"],
    editor: ["create", "read", "update"],
    user: ["read", "update"],
}

export default function Test() {

    return (
        <div>
            {
                users.map(user =>{
                    return <div key={user.name} >
                            {/* we need to render actions depending on user type */}
                            <p>{user.name}</p>
                            <div className='flex items-center'>
                                user actions : 
                                {
                                    userActionsStates[user.type].map(a => <Action key={a} a={a} />)
                                }
                            </div>
                    </div>
                })
            }

        </div>
    )
}

function Action(props : {a : string}) {
  const {a} = props
  return (
    <p className='px-2  py-1  border-[1px] mx-2 rounded-md'  >{a}</p>
  )
}

輸出例如 (2)

  • 輸出與範例 (1) 相同

關鍵變化

將每個使用者類型分組到物件鍵和值應該是您想要呈現的內容

在這種情況下,我們傳遞每個使用者類型的操作,如下所示

物件分組

在這裡,我們不是像範例 (1) 那樣渲染每個條件或建立ternary condition ,而是從分組物件userActionsStates中取得使用者操作,然後只渲染鍵值中的任何內容,瞧,這只是一行程式碼

使用物件的條件

else的呢?如果我們傳遞物件中不存在的使用者類型怎麼辦?

在這種情況下,我們可以在物件中新增一個預設鍵,該鍵將在 false 或未定義的情況下使用

像下面這樣:


const userActionsStates : Record<UserType , string[] > = {
    admin: ["create", "read", "update", "delete"],
    editor: ["create", "read", "update"],
    user: ["read", "update"],
    default : ["read"]
}

如果我們用新用戶更新用戶,它的類型不會像最後一個用戶物件那樣定義

使用新的未定義用戶類型更新用戶

然後我們將對渲染方法做一個小改變

<div className='flex items-center'>
    user actions : 
    {
        (userActionsStates[user.type] ?? userActionsStates["default"]).map(a => <Action key={a} a={a} />)
    }
</div>

使用null coalescing ??我們確保它將按預期呈現

所有條件。 :)

更新的用戶輸出

請注意

使用此方法,您可以渲染鍵值 string 、 number 、 array 、 Component 等中的任何內容。

概括

  • 易於閱讀、除錯和更新🧑‍💻

  • 看起來很酷😌

  • 更少的程式碼

這取決於你的創造力和想法💡🔥


原文出處:https://dev.to/abdoseadaa/stop-rendering-conditions-like-this-imo


共有 0 則留言