kentcdodds / ama

Ask me anything!
https://github.com/kentcdodds/ama/issues?q=is%3Aissue+is%3Aclosed
685 stars 75 forks source link

JSX Inline switch statement for enumerated states #815

Open JRhodes95 opened 4 years ago

JRhodes95 commented 4 years ago

Hey Kent,

As I've been working more with enumerated states, "OPEN", "CLOSED" etc, and moving away from using bools like isOpen I was looking for a more explicit inline control flow for conditional rendering than ternary operators { isOpen ? <OpenState /> : <ClosedState> }.

I came across a pattern of using objects as inline switch statements:

<>
{
  {
    OPEN : (<OpenState />),
    CLOSED: (<ClosedState />)
  } [openState]
}
</>

I had never seen it used before and wondered whether there are any drawbacks? As I see it:

✅ Inline code so easy to see control flow ✅ Explicit declarations of states, with ability to add a fallback by adding || <Fallback /> ✅ Easy to add new states by adding new object entries ❓ Does the creation of the object have a performance detriment over short-circuiting or ternaries?

The alternatives aren't perfect, ones I can see are:

Inline ternary

<>
{ openState === "OPEN" ? <OpenState /> : <ClosedState /> }
</>

✅ Good inline readability ❌ Difficult to add new states to the flow when requirements change

renderComponent() function

renderOpen = () => {
  switch(openState) {
    case "OPEN" : return <OpenState />
    case "CLOSED" : return <ClosedState />
    default: ...
}
return (
  <>
    {renderOpen()}
  </>
)

✅ Easier to add new states ❌ Arguably harder to read with control flow jumping around in the document ❌ I've seen this pattern get really out of hand with 10+ render functions in one component

Would be great to hear your, or anyone else's thoughts on this!