In regards to "readability", and maintainability I could argue that this:
// Declare mapconstsomethingMap={foo:Something,bar:SomethingElse};// Then use itsomethingMap[value];
...feels better than this:
// declare function with a switch inside of itconstsomethingMap=value=>{switch(value){case"foo":returnSomething;case"bar":returnSomethingElse;}};// then use itsomethingMap(value);
Default is not my concern at all, it can be replaced with case 'guest'. My problem is using an enum:
with component definitions (foo: <Bar />): it has performance costs
with direct component values (foo: Bar): it sacrifices flexibility and maintainability.
The last example you wrote is also an anti-pattern I explained.
As a hint, this code snippet alone here should be a red flag in the 90% of the cases: <Component {...props} />. By seeing the code you don't know what your component exactly is, and what props it is getting. This could be the equivalent of TS's any in React.
Can you expand on the "cost" of flexibility and maintenance of component values? I mean if the props are the same for every component (which is expected if you're returning any of those out of the same function/component), then there is no issue with it.
As for the ...props, that depends on your setup. It might be a "red flag" in vanilla JS, but it isn't one if you have a type system. Here's an example with TS to illustrate:
import{FC}from"react";typeProfileProps=JSX.IntrinsicElements["div"];typeProfileComponent=FC<Props>;constAdminProfile:ProfileComponent=props=><div{...props}/>;
constUserProfile:ProfileComponent=props=><div{...props}/>;
constDefaultProfile:ProfileComponent=props=><div{...props}/>;
constroleComponentMap={admin:AdminProfile,user:UserProfile,default:DefaultProfile};exportconstProfile:FC<ProfileProps&{readonlyrole?:keyoftypeofroleComponentMap;}>=({role="default",...props})=>{constComponent=roleComponentMap[role];// Component here is of type ProfileComponent 🎉return<Component{...props}/>;
};
Obviously this shouldn't be all on the same place, types in their own files, components as well ... but hey, is an example! ... Now, if you want to be extra safe because you don't trust TS, then you can change the Profile component a little:
That it needs an extra tool (TS) to make it somewhat useable imo already validates my concern. You still cannot SEE from the code what it is.
Why is it so obvious that all components will receive the same prop always? Even in the example there is the logged out case which makes this invalid. Sure, it works fine until I need more/different props, but why would I settle down with a solution that doesn't let me modify later? Especially when the other solution doesn't cost me any extra effort over the enum one.
but why would I settle down with a solution that doesn't let me modify later?
I agree, solutions should take the future into consideration, but what in the code above makes you think you can't modify it later? Let's say now I want to add a new property "color" to Profile, that will set the classname of the rendered profile component to be color-${color}, with the above approach is quite easy:
The "initial" cost is pretty much the same, but the long term cost of the switch/case in this scenario is higher. When you're wrapping different components inside a single component (which is the case for this component), is better to share props across them because they will be used in the same places, so ideally they should receive the same props. They might ignore some of them, and use others.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
If your concern is about defaults, you can always use the enum solution with the
??
operator:or you can just use default values:
In regards to "readability", and maintainability I could argue that this:
...feels better than this:
Default is not my concern at all, it can be replaced with
case 'guest'
. My problem is using an enum:foo: <Bar />
): it has performance costsfoo: Bar
): it sacrifices flexibility and maintainability.The last example you wrote is also an anti-pattern I explained.
As a hint, this code snippet alone here should be a red flag in the 90% of the cases:
<Component {...props} />
. By seeing the code you don't know what your component exactly is, and what props it is getting. This could be the equivalent of TS's any in React.Can you expand on the "cost" of flexibility and maintenance of component values? I mean if the props are the same for every component (which is expected if you're returning any of those out of the same function/component), then there is no issue with it.
As for the
...props
, that depends on your setup. It might be a "red flag" in vanilla JS, but it isn't one if you have a type system. Here's an example with TS to illustrate:Obviously this shouldn't be all on the same place, types in their own files, components as well ... but hey, is an example! ... Now, if you want to be extra safe because you don't trust TS, then you can change the
Profile
component a little:That it needs an extra tool (TS) to make it somewhat useable imo already validates my concern. You still cannot SEE from the code what it is.
Why is it so obvious that all components will receive the same prop always? Even in the example there is the logged out case which makes this invalid. Sure, it works fine until I need more/different props, but why would I settle down with a solution that doesn't let me modify later? Especially when the other solution doesn't cost me any extra effort over the enum one.
I used
DefaultProfile
instead, but ok...I agree, solutions should take the future into consideration, but what in the code above makes you think you can't modify it later? Let's say now I want to add a new property "color" to
Profile
, that will set the classname of the rendered profile component to becolor-${color}
, with the above approach is quite easy:With the switch/case, to achieve the same, I have to actually...
The "initial" cost is pretty much the same, but the long term cost of the
switch/case
in this scenario is higher. When you're wrapping different components inside a single component (which is the case for this component), is better to share props across them because they will be used in the same places, so ideally they should receive the same props. They might ignore some of them, and use others.