For me HOCs in general are an anti-pattern, you can always find better solutions using hooks and context.
In this particular case showing the right component should be the role of your routing. For example using react-router you can simply do:
if(!loggedIn){rerurn(<Redirectto={{path:'/login',state:{message:'You need to login to see your settings` }
}} />
)
}
Another anti-pattern is creating renderItem and such render functions. React components already functions itself. If you stick to it, you can have a much cleaner code base at the end.
The problem was also stated previously that in your examples all components will get constructed at load time for no reason. It was also stated this can be solved just by assigning the component itself to the property values instead the components with JSX definition, but that sacrifices dynamic usage, maintainability and edge case handling. This is why IMO switch-case is a superior solution.
To stick to your use case, I'd simply do the following:
constSettings=()=>{const{role}=useContext(SessionContext)switch(role){case'admin':return<AdminSettings/>case'user':return<UserSettings/>default:return<LoggedOut>Login to see your profile</LoggedOut>}}
Follows a component-only pattern. No {renderSettings(role)}/{settingsComponents[role]}, but <Settings />
No HoC magic.
It doesn't bring up performances concerns.
More readable.
Better maintainability by supporting any other cases/props.
HOC is not an anti-pattern - it is HOF if we consider any component as a function, but hooks break the main FP rule - the function purity and I consider it as a side-effect. I agree with you, the best solution for this example are routers and HOC should be used for something else.
I prefer to create some helper functions which can be used across the project:
constDefaultSettings=()=>(<p>What the Hell Are You?</p>)constselectSettings=select(when(`admin`,AdminSettings),when(`user`,UserSettings),when(`guest`,GuestSettings),()=>DefaultSettings)constUserSettings=({userRole,username})=>{constSettings=selectSettings(userRole)return(<div><h1>Settings</h1><Settingsusername={username}/></div>)}
For me HOCs in general are an anti-pattern, you can always find better solutions using hooks and context.
In this particular case showing the right component should be the role of your routing. For example using react-router you can simply do:
Another anti-pattern is creating
renderItem
and such render functions. React components already functions itself. If you stick to it, you can have a much cleaner code base at the end.The problem was also stated previously that in your examples all components will get constructed at load time for no reason. It was also stated this can be solved just by assigning the component itself to the property values instead the components with JSX definition, but that sacrifices dynamic usage, maintainability and edge case handling. This is why IMO
switch-case
is a superior solution.To stick to your use case, I'd simply do the following:
component-only
pattern. No{renderSettings(role)}
/{settingsComponents[role]}
, but<Settings />
"For me HOCs in general are an anti-pattern, you can always find better solutions using hooks and context."
Nailed it!
HOC is not an anti-pattern - it is HOF if we consider any component as a function, but hooks break the main FP rule - the function purity and I consider it as a side-effect. I agree with you, the best solution for this example are routers and HOC should be used for something else.
I prefer to create some helper functions which can be used across the project:
and use them:
Exactly!